From 844807daa720a0246ce74dbc4ec5f40914bd8dbd Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Mon, 17 Feb 2025 12:33:22 -0700 Subject: [PATCH 01/45] refactor: add changeset for new tables Signed-off-by: Jonathan Howard --- .../resources/migration/changelog-v5.6.0.xml | 733 ++++++++++++++++++ 1 file changed, 733 insertions(+) create mode 100644 src/main/resources/migration/changelog-v5.6.0.xml diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml new file mode 100644 index 0000000000..ee0801e9df --- /dev/null +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -0,0 +1,733 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE "PROJECT" + SET "AUTHORS" = JSON_BUILD_ARRAY(JSON_BUILD_OBJECT('name', "AUTHOR"))::TEXT + WHERE "AUTHOR" IS NOT NULL; + + + UPDATE "COMPONENT" + SET "AUTHORS" = JSON_BUILD_ARRAY(JSON_BUILD_OBJECT('name', "AUTHOR"))::TEXT + WHERE "AUTHOR" IS NOT NULL; + + + + + + + + + + + + + + + + CREATE + INDEX "COMPONENT_DIRECT_DEPENDENCIES_JSONB_IDX" + ON "COMPONENT" + USING GIN("DIRECT_DEPENDENCIES" JSONB_PATH_OPS); + + + + + + DELETE FROM "CONFIGPROPERTY" + WHERE "GROUPNAME" = 'artifact' + AND "PROPERTYNAME" = 'bom.validation.enabled'; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DELETE + FROM "CONFIGPROPERTY" + WHERE "GROUPNAME" = 'vuln-source' + AND "PROPERTYNAME" = 'nvd.feeds.url'; + + + + + + CREATE INDEX "COMPONENT_PROPERTY_COMPONENT_ID_IDX" + ON "COMPONENT_PROPERTY" ("COMPONENT_ID"); + + + + + + + + + + + UPDATE "PROJECT" SET "INACTIVE_SINCE" = NOW() WHERE "ACTIVE" IS FALSE + + + + + + + + + + + + + + + + + + + + + + + + + + + + CREATE INDEX "COMPONENT_BLAKE2B_256_IDX" ON "COMPONENT" ("BLAKE2B_256") WHERE "BLAKE2B_256" IS NOT NULL; + CREATE INDEX "COMPONENT_BLAKE2B_384_IDX" ON "COMPONENT" ("BLAKE2B_384") WHERE "BLAKE2B_384" IS NOT NULL; + CREATE INDEX "COMPONENT_BLAKE2B_512_IDX" ON "COMPONENT" ("BLAKE2B_512") WHERE "BLAKE2B_512" IS NOT NULL; + CREATE INDEX "COMPONENT_BLAKE3_IDX" ON "COMPONENT" ("BLAKE3") WHERE "BLAKE3" IS NOT NULL; + CREATE INDEX "COMPONENT_MD5_IDX" ON "COMPONENT" ("MD5") WHERE "MD5" IS NOT NULL; + CREATE INDEX "COMPONENT_SHA1_IDX" ON "COMPONENT" ("SHA1") WHERE "SHA1" IS NOT NULL; + CREATE INDEX "COMPONENT_SHA_256_IDX" ON "COMPONENT" ("SHA_256") WHERE "SHA_256" IS NOT NULL; + CREATE INDEX "COMPONENT_SHA_384_IDX" ON "COMPONENT" ("SHA_384") WHERE "SHA_384" IS NOT NULL; + CREATE INDEX "COMPONENT_SHA_512_IDX" ON "COMPONENT" ("SHA_512") WHERE "SHA_512" IS NOT NULL; + CREATE INDEX "COMPONENT_SHA3_256_IDX" ON "COMPONENT" ("SHA3_256") WHERE "SHA3_256" IS NOT NULL; + CREATE INDEX "COMPONENT_SHA3_384_IDX" ON "COMPONENT" ("SHA3_384") WHERE "SHA3_384" IS NOT NULL; + CREATE INDEX "COMPONENT_SHA3_512_IDX" ON "COMPONENT" ("SHA3_512") WHERE "SHA3_512" IS NOT NULL; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3951a8d9bdc5d8cef87d0e9be23e139f26163c50 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Mon, 24 Feb 2025 10:52:58 -0700 Subject: [PATCH 02/45] feat: add role and mappedrole classes (#2) Signed-off-by: Allen Shearin --- .../org/dependencytrack/model/MappedRole.java | 200 ++++++++++++++++++ .../java/org/dependencytrack/model/Role.java | 161 ++++++++++++++ .../resources/migration/changelog-v5.6.0.xml | 63 +++++- 3 files changed, 417 insertions(+), 7 deletions(-) create mode 100644 apiserver/src/main/java/org/dependencytrack/model/MappedRole.java create mode 100644 apiserver/src/main/java/org/dependencytrack/model/Role.java diff --git a/apiserver/src/main/java/org/dependencytrack/model/MappedRole.java b/apiserver/src/main/java/org/dependencytrack/model/MappedRole.java new file mode 100644 index 0000000000..6480e4f9a2 --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/model/MappedRole.java @@ -0,0 +1,200 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.model; + +import alpine.model.LdapUser; +import alpine.model.ManagedUser; +import alpine.model.OidcUser; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.jdo.annotations.Column; +import javax.jdo.annotations.Element; +import javax.jdo.annotations.Extension; +import javax.jdo.annotations.FetchGroup; +import javax.jdo.annotations.IdGeneratorStrategy; +import javax.jdo.annotations.Join; +import javax.jdo.annotations.Order; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; +import javax.jdo.annotations.Unique; + +/** + * Model for associating a role on a given project with users. + * + * @author Allen Shearin + * @since 5.6.0 + */ +@PersistenceCapable(table = "PROJECT_ACCESS_ROLES") +@Unique(name = "LDAPUSERS_PROJECTS_ROLES_COMPOSITE_IDX", + table = "LDAPUSERS_PROJECTS_ROLES", + members = { "ldapUsers", "project", "role" }, + deferred = "true") +@Unique(name = "MANAGEDUSERS_PROJECTS_ROLES_COMPOSITE_IDX", + table = "MANAGEDUSERS_PROJECTS_ROLES", + members = { "managedUsers", "project", "role" }, + deferred = "true") +@Unique(name = "OIDCUSERS_PROJECTS_ROLES_COMPOSITE_IDX", + table = "OIDCUSERS_PROJECTS_ROLES", + members = { "oidcUsers", "project", "role" }, + deferred = "true") +@FetchGroup(name = "ALL", members = { + @Persistent(name = "role"), + @Persistent(name = "project"), + @Persistent(name = "ldapUsers"), + @Persistent(name = "managedUsers"), + @Persistent(name = "oidcUsers") +}) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MappedRole implements Serializable { + + private static final long serialVersionUID = 1982348710987098723L; + + /** + * Defines JDO fetch groups for this class. + */ + public enum FetchGroup { + ALL + } + + @PrimaryKey + @Persistent(valueStrategy = IdGeneratorStrategy.NATIVE) + @JsonIgnore + private long id; + + @Persistent + @Column(name = "ROLE_ID", allowsNull = "false") + @JsonIgnore + private Role role; + + @Persistent + @Column(name = "PROJECT_ID", allowsNull = "false") + @JsonIgnore + private Project project; + + @Persistent(table = "LDAPUSERS_PROJECTS_ROLES", defaultFetchGroup = "true") + @Join(column = "PROJECT_ACCESS_ROLE_ID") + @Element(column = "LDAPUSER_ID") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + private List ldapUsers; + + @Persistent(table = "MANAGEDUSERS_PROJECTS_ROLES") + @Join(column = "PROJECT_ACCESS_ROLE_ID") + @Element(column = "MANAGEDUSER_ID") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + private List managedUsers; + + @Persistent(table = "OIDCUSERS_PROJECTS_ROLES") + @Join(column = "PROJECT_ACCESS_ROLE_ID") + @Element(column = "OIDCUSER_ID") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + private List oidcUsers; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } + + public List getLdapUsers() { + return ldapUsers; + } + + public void setLdapUsers(List ldapUsers) { + this.ldapUsers = ldapUsers; + } + + public void addLdapUsers(LdapUser... ldapUsers) { + if (this.ldapUsers == null) { + this.ldapUsers = new ArrayList<>(Arrays.asList(ldapUsers)); + + return; + } + + for (var user : ldapUsers) + if (!this.ldapUsers.contains(user)) + this.ldapUsers.add(user); + } + + public List getManagedUsers() { + return managedUsers; + } + + public void setManagedUsers(List managedUsers) { + this.managedUsers = managedUsers; + } + + public void addManagedUsers(ManagedUser... managedUsers) { + if (this.managedUsers == null) { + this.managedUsers = new ArrayList<>(Arrays.asList(managedUsers)); + + return; + } + + for (var user : managedUsers) + if (!this.managedUsers.contains(user)) + this.managedUsers.add(user); + } + + public List getOidcUsers() { + return oidcUsers; + } + + public void setOidcUsers(List oidcUsers) { + this.oidcUsers = oidcUsers; + } + + public void addOidcUsers(OidcUser... oidcUsers) { + if (this.oidcUsers == null) { + this.oidcUsers = new ArrayList<>(Arrays.asList(oidcUsers)); + + return; + } + + for (var user : oidcUsers) + if (!this.oidcUsers.contains(user)) + this.oidcUsers.add(user); + } + +} \ No newline at end of file diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java new file mode 100644 index 0000000000..8ba1998a6b --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -0,0 +1,161 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.model; + +import alpine.common.validation.RegexSequence; +import alpine.model.Permission; +import alpine.server.json.TrimmedStringDeserializer; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.jdo.annotations.Column; +import javax.jdo.annotations.Element; +import javax.jdo.annotations.Extension; +import javax.jdo.annotations.FetchGroup; +import javax.jdo.annotations.IdGeneratorStrategy; +import javax.jdo.annotations.Join; +import javax.jdo.annotations.Order; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; +import javax.jdo.annotations.Unique; + +/** + * Model for tracking roles. Roles define static sets of permissions + * that can be applied to a user with the scope of a project. + * + * @author Allen Shearin + * @since 5.6.0 + */ +@PersistenceCapable +@FetchGroup(name = "ALL", members = { + @Persistent(name = "name"), + @Persistent(name = "description"), + @Persistent(name = "permissions"), +}) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Role implements Serializable { + + private static final long serialVersionUID = -7592438796591673355L; + + /** + * Defines JDO fetch groups for this class. + */ + public enum FetchGroup { + ALL + } + + @PrimaryKey + @Persistent(valueStrategy = IdGeneratorStrategy.NATIVE) + @JsonIgnore + private long id; + + @Persistent + @Unique(name = "ROLE_NAME_IDX", deferred = "true") + @Column(name = "NAME", jdbcType = "VARCHAR", allowsNull = "false") + @NotBlank + @Size(min = 1, max = 255) + @JsonDeserialize(using = TrimmedStringDeserializer.class) + @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, + message = "The name may only contain printable characters") + private String name; + + @Persistent + @Column(name = "DESCRIPTION", jdbcType = "VARCHAR") + @Size(max = 255) + @JsonDeserialize(using = TrimmedStringDeserializer.class) + @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, + message = "The description may only contain printable characters") + private String description; + + @Persistent(table = "ROLES_PERMISSIONS", defaultFetchGroup = "true") + @Unique(name = "ROLES_PERMISSIONS_IDX") + @Join(column = "ROLE_ID") + @Element(column = "PERMISSION_ID") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "name ASC")) + private List permissions; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } + + public void addPermissions(Permission... permissions) { + if (this.permissions == null) { + this.permissions = new ArrayList<>(Arrays.asList(permissions)); + + return; + } + + for (var permission : permissions) + if (!this.permissions.contains(permission)) + this.permissions.add(permission); + } + + @Override + public String toString() { + var permissionStrings = permissions.stream() + .map(permission -> permission.getName()) + .toList(); + + return "%s{id=%d, name='%s', description='%s', permissions=%s}".formatted( + getClass().getSimpleName(), + id, + name, + description != null ? description : "", + permissionStrings); + } +} diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml index ee0801e9df..c9196a988d 100644 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -660,17 +660,31 @@ - + - + deferrable="true" initiallyDeferred="true" deleteCascade="true" + validateUnique="true" validateForeignKey="true" /> + + + + + + + + @@ -678,15 +692,25 @@ + deferrable="true" initiallyDeferred="true" deleteCascade="true" + validateUnique="true" validateForeignKey="true" /> + deferrable="true" initiallyDeferred="true" deleteCascade="true" + validateUnique="true" validateForeignKey="true" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a538ecf873df54bbb70e109e8aeb4f211a7189d3 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Thu, 20 Feb 2025 09:54:43 -0700 Subject: [PATCH 03/45] refactor: add changeset for new tables Signed-off-by: Jonathan Howard --- .../main/resources/META-INF/persistence.xml | 1 + .../resources/migration/changelog-v5.6.0.xml | 115 ++++++++++-------- 2 files changed, 64 insertions(+), 52 deletions(-) diff --git a/apiserver/src/main/resources/META-INF/persistence.xml b/apiserver/src/main/resources/META-INF/persistence.xml index 718c00f915..6dd905e48b 100644 --- a/apiserver/src/main/resources/META-INF/persistence.xml +++ b/apiserver/src/main/resources/META-INF/persistence.xml @@ -45,6 +45,7 @@ org.dependencytrack.model.FindingAttribution org.dependencytrack.model.License org.dependencytrack.model.LicenseGroup + org.dependencytrack.model.MappedRole org.dependencytrack.model.NotificationPublisher org.dependencytrack.model.NotificationRule org.dependencytrack.model.Policy diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml index c9196a988d..61eca00ace 100644 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -642,64 +642,67 @@ - + + + + + + + + + + + + + + + - - + + + + + + + + + + - - - + + - + - - - - - - - - - - - + + + + + referencedTableName="PROJECT" referencedColumnNames="ID" /> + + referencedTableName="ROLE" referencedColumnNames="ID" /> @@ -714,14 +717,13 @@ + referencedTableName="LDAPUSER" referencedColumnNames="ID" /> + + referencedTableName="PROJECT_ACCESS_ROLES" referencedColumnNames="ID" /> @@ -737,14 +739,13 @@ + referencedTableName="MANAGEDUSER" referencedColumnNames="ID" /> + + referencedTableName="PROJECT_ACCESS_ROLES" referencedColumnNames="ID" /> @@ -759,24 +760,34 @@ + referencedTableName="OIDCUSER" referencedColumnNames="ID" /> + + referencedTableName="PROJECT_ACCESS_ROLES" referencedColumnNames="ID" /> - - - + + + - - - + + + + From 62aa1ea784a8330ed2c964c4adfa7e2c21dd68d2 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Fri, 21 Feb 2025 11:41:01 -0700 Subject: [PATCH 04/45] fix: changeset unique constraints Signed-off-by: Jonathan Howard --- .../resources/migration/changelog-v5.6.0.xml | 102 ++++++++++-------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml index 61eca00ace..caad54dfb6 100644 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -670,7 +670,9 @@ - + @@ -680,29 +682,45 @@ - + - + - + - + - + @@ -716,14 +734,21 @@ - + - + referencedTableName="PROJECT_ACCESS_ROLES" referencedColumnNames="ID" + deferrable="true" initiallyDeferred="true" deleteCascade="false" + validateUnique="true" validateForeignKey="true" /> @@ -737,15 +762,21 @@ - + referencedTableName="MANAGEDUSER" referencedColumnNames="ID" + deferrable="true" initiallyDeferred="true" deleteCascade="false" + validateUnique="true" validateForeignKey="true" /> - + referencedTableName="PROJECT_ACCESS_ROLES" referencedColumnNames="ID" + deferrable="true" initiallyDeferred="true" deleteCascade="false" + validateUnique="true" validateForeignKey="true" /> @@ -759,35 +790,22 @@ - + - + referencedTableName="PROJECT_ACCESS_ROLES" referencedColumnNames="ID" + deferrable="true" initiallyDeferred="true" deleteCascade="false" + validateUnique="true" validateForeignKey="true" /> - - - - - - - - - - From 7e7bf3141c05dbf7fe9e4182c02631aaa3096bec Mon Sep 17 00:00:00 2001 From: jmayer-lm Date: Tue, 25 Feb 2025 15:02:10 -0500 Subject: [PATCH 05/45] Define new Role permissisons & Initial creation of RoleResource.java (#5) Signed-off-by: jmayer-lm --- .../org/dependencytrack/auth/Permissions.java | 10 + .../resources/v1/RoleResource.java | 180 ++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java diff --git a/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java b/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java index 982eefe1a7..a8e124a6b8 100644 --- a/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java +++ b/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java @@ -61,6 +61,11 @@ public enum Permissions { POLICY_MANAGEMENT_READ("Allows reading of policies"), POLICY_MANAGEMENT_UPDATE("Allows the modification of a policy"), POLICY_MANAGEMENT_DELETE("Allows the deletion of a policy"), + ROLE_MANAGEMENT("Allows the creation, modification, and deletion of roles"), + ROLE_MANAGEMENT_CREATE("Allows the creation of roles"), + ROLE_MANAGEMENT_READ("Allows reading of roles"), + ROLE_MANAGEMENT_UPDATE("Allows update of roles"), + ROLE_MANAGEMENT_DELETE("Allows the deletion of roles"), TAG_MANAGEMENT("Allows the modification and deletion of tags"), TAG_MANAGEMENT_DELETE("Allows the deletion of a tag"), VIEW_BADGES("Provides the ability to view badges"); @@ -111,6 +116,11 @@ public static class Constants { public static final String POLICY_MANAGEMENT_READ = "POLICY_MANAGEMENT_READ"; public static final String POLICY_MANAGEMENT_UPDATE = "POLICY_MANAGEMENT_UPDATE"; public static final String POLICY_MANAGEMENT_DELETE = "POLICY_MANAGEMENT_DELETE"; + public static final String ROLE_MANAGEMENT = "ROLE_MANAGEMENT"; + public static final String ROLE_MANAGEMENT_CREATE = "ROLE_MANAGEMENT_CREATE"; + public static final String ROLE_MANAGEMENT_READ = "ROLE_MANAGEMENT_READ"; + public static final String ROLE_MANAGEMENT_UPDATE = "ROLE_MANAGEMENT_UPDATE"; + public static final String ROLE_MANAGEMENT_DELETE = "ROLE_MANAGEMENT_DELETE"; public static final String TAG_MANAGEMENT = "TAG_MANAGEMENT"; public static final String TAG_MANAGEMENT_DELETE = "TAG_MANAGEMENT_DELETE"; public static final String VIEW_BADGES = "VIEW_BADGES"; diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java new file mode 100644 index 0000000000..34eada7cc3 --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -0,0 +1,180 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.resources.v1; + +import alpine.common.logging.Logger; +import alpine.model.Permission; +import alpine.model.Role; +import alpine.model.UserPrincipal; +import alpine.server.auth.PermissionRequired; +import alpine.server.resources.AlpineResource; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityRequirements; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +import org.dependencytrack.auth.Permissions; +import org.dependencytrack.model.validation.ValidUuid; +import org.dependencytrack.persistence.QueryManager; +import org.owasp.security.logging.SecurityMarkers; + +import java.util.List; + +/** + * JAX-RS resources for processing roles. + * + * @author Johnny Mayer + * @since 5.6.0 + */ +@Path("/v1/role") +@Tag(name = "role") +@SecurityRequirements({ + @SecurityRequirement(name = "ApiKeyAuth"), + @SecurityRequirement(name = "BearerAuth") +}) +public class RoleResource extends AlpineResource { + + private static final Logger LOGGER = Logger.getLogger(RoleResource.class); + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Returns a list of all roles", + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

" + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "A list of all roles", + headers = @Header(name = TOTAL_COUNT_HEADER, description = "The total number of roles", schema = @Schema(format = "integer")), + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Role.class))) + ), + @ApiResponse(responseCode = "401", description = "Unauthorized") + }) + @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_READ}) + public Response getRoles() { + return Response.ok(roles).header(TOTAL_COUNT_HEADER, totalCount).build(); + } + + @GET + @Path("/{uuid}") + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Returns a specific role", + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

" + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "A specific role", + content = @Content(schema = @Schema(implementation = Role.class)) + ), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The role could not be found") + }) + @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_READ}) + public Response getRole( + @Parameter(description = "The UUID of the role to retrieve", schema = @Schema(type = "string", format = "uuid"), required = true) + @PathParam("uuid") @ValidUuid String uuid) { + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Returned role: " + role.getName()); + return Response.ok(role).build(); + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Creates a new role", + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_CREATE

" + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "201", + description = "The created role", + content = @Content(schema = @Schema(implementation = Role.class)) + ), + @ApiResponse(responseCode = "401", description = "Unauthorized") + }) + @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_CREATE}) + public Response createRole(Role jsonRole) { + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Created role: " + role.getName()); + return Response.ok(role).build(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Updates a role's fields", + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_UPDATE

" + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "The updated role", + content = @Content(schema = @Schema(implementation = Role.class)) + ), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The role could not be found") + }) + @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_UPDATE}) + public Response updateRole(Role jsonRole) { + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Updated role: " + role.getName()); + return Response.ok(role).build(); + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Deletes a role", + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_DELETE

" + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Role removed successfully"), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The role could not be found") + }) + @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_DELETE}) + public Response deleteRole(Role jsonRole) { + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Delete role: " + role.getName()); + return Response.ok(role).build(); + } + + + +} From d0cd774d308a8d21a72f6a6d3345473798c9533f Mon Sep 17 00:00:00 2001 From: lmphil <126618132+lmphil@users.noreply.github.com> Date: Wed, 26 Feb 2025 18:20:36 -0400 Subject: [PATCH 06/45] add roleQueryManager method stubs (#6) Signed-off-by: lmphil <126618132+lmphil@users.noreply.github.com> --- .../persistence/QueryManager.java | 8 ++++ .../persistence/RoleQueryManager.java | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 99f78c63e9..2a85e2b0e3 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -1088,6 +1088,14 @@ public synchronized RepositoryMetaComponent synchronizeRepositoryMetaComponent(f return getRepositoryQueryManager().synchronizeRepositoryMetaComponent(transientRepositoryMetaComponent); } + public boolean addRoleToUser(UserPrincipal principal, Role role, String roleName, String projectName){ + return getRoleQueryManager().addRoleToUser(principal, role, roleName, projectName); + } + + public boolean removeRoleFromUser(UserPrincipal principal, Role role, String roleName, String projectName){ + return getRoleQueryManager().removeRoleFromUser(principal, role, roleName, projectName); + } + public NotificationRule createNotificationRule(String name, NotificationScope scope, NotificationLevel level, NotificationPublisher publisher) { return getNotificationQueryManager().createNotificationRule(name, scope, level, publisher); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java new file mode 100644 index 0000000000..dc7924137a --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -0,0 +1,40 @@ +package org.dependencytrack.persistence; + +import java.nio.file.attribute.UserPrincipal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; + +import org.dependencytrack.model.Role; + +import alpine.common.logging.Logger; +import alpine.model.Permission; +import alpine.resources.AlpineRequest; + +final class RoleQueryManager extends QueryManager implements IQueryManager { + + private static final Logger LOGGER = Logger.getLogger(ProjectQueryManager.class); + + RoleQueryManager(final PersistenceManager pm) { + super(pm); + } + + RoleQueryManager(final PersistenceManager pm, final AlpineRequest request) { + super(pm, request); + } + + boolean addRoleToUser(UserPrincipal principal, Role role, String roleName, String projectName){ + //WARNING: This method is a stub. + //TODO: Implement addRoleToUser + return true; + } + + boolean removeRoleFromUser(UserPrincipal principal, Role role, String roleName, String projectName){ + //WARNING: This method is a stub. + //TODO: Implement removeRoleFromUser + return true; + } +} From 63d8c2f8b81a4e31dc3cebb340b968c37e27ddaa Mon Sep 17 00:00:00 2001 From: jmayer-lm Date: Thu, 27 Feb 2025 12:16:22 -0500 Subject: [PATCH 07/45] Add /v1/user Endpoints & CRUD Method Stubs (#7) Signed-off-by: jmayer-lm --- .../persistence/QueryManager.java | 20 +++ .../persistence/RoleQueryManager.java | 30 ++++- .../resources/v1/UserResource.java | 124 ++++++++++++++++-- 3 files changed, 161 insertions(+), 13 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 2a85e2b0e3..bdc24828aa 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -845,6 +845,26 @@ public void deletePolicyCondition(PolicyCondition policyCondition) { getPolicyQueryManager().deletePolicyCondition(policyCondition); } + public Role createRole(Role role) { + return getRoleQueryManager().createRole(role); + } + + public List getRoles() { + return getRoleQueryManager().getRoles(); + } + + public Role getRole(String uuid) { + return getRoleQueryManager().getRole(null); + } + + public Role updateRole(Role role) { + return getRoleQueryManager().updateRole(role); + } + + public boolean deleteRole(String uuid, boolean value) { + return getRoleQueryManager().deleteRole(uuid, value); + } + public Vulnerability createVulnerability(Vulnerability vulnerability, boolean commitIndex) { return getVulnerabilityQueryManager().createVulnerability(vulnerability, commitIndex); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index dc7924137a..94dae4f731 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -1,17 +1,14 @@ package org.dependencytrack.persistence; import java.nio.file.attribute.UserPrincipal; -import java.util.HashMap; +import java.util.Collections; import java.util.List; -import java.util.Map; import javax.jdo.PersistenceManager; -import javax.jdo.Query; import org.dependencytrack.model.Role; import alpine.common.logging.Logger; -import alpine.model.Permission; import alpine.resources.AlpineRequest; final class RoleQueryManager extends QueryManager implements IQueryManager { @@ -26,6 +23,31 @@ final class RoleQueryManager extends QueryManager implements IQueryManager { super(pm, request); } + public Role createRole(Role role) { + // TODO:Implement role creation logic + return role; + } + + public List getRoles() { + // TODO:Implement role retrieval logic + return Collections.emptyList(); + } + + public Role getRole(String uuid) { + // TODO:Implement role retrieval logic + return null; + } + + public Role updateRole(Role role) { + // TODO:Implement role update logic + return role; + } + + public boolean deleteRole(String uuid, boolean value) { + // TODO:Implement role deletion logic + return false; + } + boolean addRoleToUser(UserPrincipal principal, Role role, String roleName, String projectName){ //WARNING: This method is a stub. //TODO: Implement addRoleToUser diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 0c346259b8..3f797283ff 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -18,6 +18,22 @@ */ package org.dependencytrack.resources.v1; +import java.security.Principal; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.dependencytrack.auth.Permissions; +import org.dependencytrack.event.kafka.KafkaEventDispatcher; +import org.dependencytrack.model.IdentifiableObject; +import org.dependencytrack.model.Role; +import org.dependencytrack.notification.NotificationConstants; +import org.dependencytrack.notification.NotificationGroup; +import org.dependencytrack.notification.NotificationScope; +import org.dependencytrack.persistence.QueryManager; +import org.dependencytrack.proto.notification.v1.UserSubject; +import org.owasp.security.logging.SecurityMarkers; + import alpine.Config; import alpine.common.logging.Logger; import alpine.model.LdapUser; @@ -72,17 +88,9 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import javax.jdo.Query; -import java.security.Principal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; /** * JAX-RS resources for processing users. @@ -846,4 +854,102 @@ private UserSubject buildUserSubject(final String username, final String email) Optional.ofNullable(email).ifPresent(userBuilder::setEmail); return userBuilder.build(); } + + @POST + @Path("/{username}/role") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Adds role to specific user.", + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "Updated user with a specific role", + content = @Content(schema = @Schema(implementation = UserPrincipal.class)) + ), + @ApiResponse(responseCode = "304", description = "The user has already been assigned to this role."), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The user or role could not be found") + }) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) + public Response addRoleToUser( + @Parameter(description = "A valid username", required = true) + @PathParam("username") String username, + @Parameter(description = "The UUID of the role to associate username with", required = true) + IdentifiableObject identifiableObject, + @Parameter(description = "The name of the role", required = true) + @QueryParam("roleName") String roleName, + @Parameter(description = "The name of the project", required = true) + @QueryParam("projectName") String projectName) { + try (QueryManager qm = new QueryManager()) { + final Role role = qm.getObjectByUuid(Role.class, identifiableObject.getUuid()); + if (role == null) + return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + + UserPrincipal principal = qm.getUserPrincipal(username); + if (principal == null) + return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); + + final boolean modified = qm.addRoleToUser(principal, role, roleName, projectName); + principal = qm.getObjectById(principal.getClass(), principal.getId()); + if (modified) { + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added role membership for: %s / role: %s / project: %s".formatted(principal.getName(), role.getName(), projectName)); + return Response.ok(principal).build(); + } + + return Response.status(Response.Status.NOT_MODIFIED).entity("The user is already a member of the specified role.").build(); + } + } + + @DELETE + @Path("/{username}/role") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Removes role from specific user.", + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" +) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "Updated user with a specific role removed", + content = @Content(schema = @Schema(implementation = UserPrincipal.class)) + ), + @ApiResponse(responseCode = "204", description = "The role has been successfully removed from the user"), + @ApiResponse(responseCode = "304", description = "The user is not a member of the specified role"), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The user or role could not be found") +}) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) + public Response removeRoleFromUser( + @Parameter(description = "A valid username", required = true) + @PathParam("username") String username, + @Parameter(description = "The UUID of the role to remove from the username", required = true) + IdentifiableObject identifiableObject, + @Parameter(description = "The name of the role", required = true) + @QueryParam("roleName") String roleName, + @Parameter(description = "The name of the project", required = true) + @QueryParam("projectName") String projectName) { + try (QueryManager qm = new QueryManager()) { + final Role role = qm.getObjectByUuid(Role.class, identifiableObject.getUuid()); + if (role == null) + return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + + UserPrincipal principal = qm.getUserPrincipal(username); + if (principal == null) + return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); + + final boolean modified = qm.removeRoleFromUser(principal, role, roleName, projectName); + + principal = qm.getObjectById(principal.getClass(), principal.getId()); + if (modified) { + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Removed role membership for: %s / role: %s / project: %s".formatted(principal.getName(), role.getName(), projectName)); + return Response.noContent().build(); + } + + return Response.status(Response.Status.NOT_MODIFIED).entity("The user is not a member of the specified role.").build(); + } + } } From 0400b83bbf54c3f75de7ca982e3b20b741af5e9c Mon Sep 17 00:00:00 2001 From: EphraimEM Date: Thu, 27 Feb 2025 11:19:37 -0600 Subject: [PATCH 08/45] Add default roles and permissions for project management (#8) Signed-off-by: EphraimEM --- .../persistence/DefaultObjectGenerator.java | 447 ++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java diff --git a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java new file mode 100644 index 0000000000..fa2b4c030c --- /dev/null +++ b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java @@ -0,0 +1,447 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence; + +import alpine.Config; +import alpine.common.logging.Logger; +import alpine.model.ConfigProperty; +import alpine.model.ManagedUser; +import alpine.model.Permission; +import alpine.model.Team; +import alpine.server.auth.PasswordService; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import org.dependencytrack.auth.Permissions; +import org.dependencytrack.common.ConfigKey; +import org.dependencytrack.model.ConfigPropertyConstants; +import org.dependencytrack.model.License; +import org.dependencytrack.model.RepositoryType; +import org.dependencytrack.parser.spdx.json.SpdxLicenseDetailParser; +import org.dependencytrack.persistence.defaults.DefaultLicenseGroupImporter; +import org.dependencytrack.util.NotificationUtil; +import org.dependencytrack.util.WaitingLockConfiguration; + +import java.io.IOException; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static net.javacrumbs.shedlock.core.LockAssert.assertLocked; +import static org.dependencytrack.model.ConfigPropertyConstants.INTERNAL_DEFAULT_OBJECTS_VERSION; +import static org.dependencytrack.util.LockProvider.executeWithLockWaiting; + +/** + * Creates default objects on an empty database. + * + * @author Steve Springett + * @since 3.0.0 + */ +public class DefaultObjectGenerator implements ServletContextListener { + + private static final Logger LOGGER = Logger.getLogger(DefaultObjectGenerator.class); + + /** + * {@inheritDoc} + */ + @Override + public void contextInitialized(final ServletContextEvent event) { + if (!Config.getInstance().getPropertyAsBoolean(ConfigKey.INIT_TASKS_ENABLED)) { + LOGGER.info("Not populating database with default objects because %s is disabled" + .formatted(ConfigKey.INIT_TASKS_ENABLED.getPropertyName())); + return; + } + + // Ensure that this task is only executed by a single instance at once. + // Wait for lock acquisition rather than simply skipping execution, + // since application logic may depend on default objects being present. + final var lockConfig = new WaitingLockConfiguration( + /* createdAt */ Instant.now(), + /* name */ getClass().getName(), + /* lockAtMostFor */ Duration.ofMinutes(5), + /* lockAtLeastFor */ Duration.ZERO, + /* pollInterval */ Duration.ofSeconds(1), + /* waitTimeout */ Duration.ofMinutes(5) + ); + + try { + executeWithLockWaiting(lockConfig, this::executeLocked); + } catch (Throwable t) { + if (Config.getInstance().getPropertyAsBoolean(ConfigKey.INIT_AND_EXIT)) { + // Make absolutely sure that we exit with non-zero code so + // the container orchestrator knows to restart the container. + LOGGER.error("Failed to populate database with default objects", t); + System.exit(1); + } + + throw new RuntimeException("Failed to populate database with default objects", t); + } + + if (Config.getInstance().getPropertyAsBoolean(ConfigKey.INIT_AND_EXIT)) { + LOGGER.info("Exiting because %s is enabled".formatted(ConfigKey.INIT_AND_EXIT.getPropertyName())); + System.exit(0); + } + } + + private void executeLocked() { + assertLocked(); + + if (!shouldExecute()) { + LOGGER.info("Default objects already populated for build %s (timestamp: %s); Skipping".formatted( + Config.getInstance().getApplicationBuildUuid(), + Config.getInstance().getApplicationBuildTimestamp() + )); + return; + } + + // TODO: Make population transactional with recordDefaultObjectsVersion(). + + LOGGER.info("Initializing default object generator"); + loadDefaultPermissions(); + loadDefaultPersonas(); + loadDefaultLicenses(); + loadDefaultLicenseGroups(); + loadDefaultRepositories(); + loadDefaultConfigProperties(); + loadDefaultNotificationPublishers(); + + recordDefaultObjectsVersion(); + } + + /** + * {@inheritDoc} + */ + @Override + public void contextDestroyed(final ServletContextEvent event) { + /* Intentionally blank to satisfy interface */ + } + + private boolean shouldExecute() { + try (final var qm = new QueryManager()) { + final ConfigProperty configProperty = qm.getConfigProperty( + INTERNAL_DEFAULT_OBJECTS_VERSION.getGroupName(), + INTERNAL_DEFAULT_OBJECTS_VERSION.getPropertyName() + ); + + return configProperty == null + || configProperty.getPropertyValue() == null + || !Config.getInstance().getApplicationBuildUuid().equals(configProperty.getPropertyValue()); + } + } + + private void recordDefaultObjectsVersion() { + try (final var qm = new QueryManager()) { + qm.runInTransaction(() -> { + final ConfigProperty configProperty = qm.getConfigProperty( + INTERNAL_DEFAULT_OBJECTS_VERSION.getGroupName(), + INTERNAL_DEFAULT_OBJECTS_VERSION.getPropertyName() + ); + + configProperty.setPropertyValue(Config.getInstance().getApplicationBuildUuid()); + }); + } + } + + /** + * Loads the default licenses into the database if no license data exists. + */ + public static void loadDefaultLicenses() { + try (QueryManager qm = new QueryManager()) { + LOGGER.info("Synchronizing SPDX license definitions to datastore"); + + final SpdxLicenseDetailParser parser = new SpdxLicenseDetailParser(); + try { + final List licenses = parser.getLicenseDefinitions(); + for (final License license : licenses) { + LOGGER.debug("Synchronizing: " + license.getName()); + qm.synchronizeLicense(license, false); + } + } catch (IOException e) { + LOGGER.error("An error occurred during the parsing SPDX license definitions"); + LOGGER.error(e.getMessage()); + } + } + } + + /** + * Loads the default license groups into the database if no license groups exists. + */ + private void loadDefaultLicenseGroups() { + try (QueryManager qm = new QueryManager()) { + final DefaultLicenseGroupImporter importer = new DefaultLicenseGroupImporter(qm); + if (! importer.shouldImport()) { + return; + } + LOGGER.info("Adding default license group definitions to datastore"); + try { + importer.loadDefaults(); + } catch (IOException e) { + LOGGER.error("An error occurred loading default license group definitions"); + LOGGER.error(e.getMessage()); + } + } + } + + /** + * Loads the default permissions + */ + public void loadDefaultPermissions() { + try (QueryManager qm = new QueryManager()) { + LOGGER.info("Synchronizing permissions to datastore"); + for (final Permissions permission : Permissions.values()) { + if (qm.getPermission(permission.name()) == null) { + LOGGER.debug("Creating permission: " + permission.name()); + qm.createPermission(permission.name(), permission.getDescription()); + } + } + } + } + + /** + * Loads the default users and teams + */ + private void loadDefaultPersonas() { + try (QueryManager qm = new QueryManager()) { + if (!qm.getManagedUsers().isEmpty() && !qm.getTeams().isEmpty()) { + return; + } + LOGGER.info("Adding default users and teams to datastore"); + LOGGER.debug("Creating user: admin"); + ManagedUser admin = qm.createManagedUser("admin", "Administrator", "admin@localhost", + new String(PasswordService.createHash("admin".toCharArray())), true, true, false); + + LOGGER.debug("Creating team: Administrators"); + final Team sysadmins = qm.createTeam("Administrators", false); + LOGGER.debug("Creating team: Portfolio Managers"); + final Team managers = qm.createTeam("Portfolio Managers", false); + LOGGER.debug("Creating team: Automation"); + final Team automation = qm.createTeam("Automation", true); + LOGGER.debug("Creating team: Badge Viewers"); + final Team badges = qm.createTeam("Badge Viewers", true); + + final List fullList = qm.getPermissions(); + + LOGGER.debug("Assigning default permissions to teams"); + sysadmins.setPermissions(fullList); + managers.setPermissions(getPortfolioManagersPermissions(fullList)); + automation.setPermissions(getAutomationPermissions(fullList)); + badges.setPermissions(getBadgesPermissions(fullList)); + + qm.persist(sysadmins); + qm.persist(managers); + qm.persist(automation); + qm.persist(badges); + + LOGGER.debug("Adding admin user to System Administrators"); + qm.addUserToTeam(admin, sysadmins); + + admin = qm.getObjectById(ManagedUser.class, admin.getId()); + admin.setPermissions(qm.getPermissions()); + qm.persist(admin); + } + } + + private List getPortfolioManagersPermissions(final List fullList) { + final List permissions = new ArrayList<>(); + for (final Permission permission: fullList) { + if (permission.getName().equals(Permissions.Constants.VIEW_PORTFOLIO) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_READ) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE)) { + permissions.add(permission); + } + } + return permissions; + } + + private List getAutomationPermissions(final List fullList) { + final List permissions = new ArrayList<>(); + for (final Permission permission: fullList) { + if (permission.getName().equals(Permissions.Constants.VIEW_PORTFOLIO) || + permission.getName().equals(Permissions.Constants.BOM_UPLOAD)) { + permissions.add(permission); + } + } + return permissions; + } + + private List getBadgesPermissions(final List fullList) { + final List permissions = new ArrayList<>(); + for (final Permission permission : fullList) { + if (permission.getName().equals(Permissions.Constants.VIEW_BADGES)) { + permissions.add(permission); + } + } + return permissions; + } + + /** + * Loads the default Roles + */ + private void loadDefaultRoles() { + try (QueryManager qm = new QueryManager()) { + if (!qm.getRoles().isEmpty()) { + return; + } + LOGGER.info("Adding default roles to datastore"); + LOGGER.debug("Creating role: Project Admin"); + final Role projectAdmin = qm.createRole("Project Admin", false); + LOGGER.debug("Creating role: Project Auditor"); + final Role projectAuditor = qm.createRole("Project Auditor", false); + LOGGER.debug("Creating role: Project Editor"); + final Role projectEditor = qm.createRole("Project Editor", false); + LOGGER.debug("Creating role: Project Viewer"); + final Role projectViewer = qm.createRole("Project Viewer", true); + + final List fullList = qm.getPermissions(); + + LOGGER.debug("Assigning default permissions to roles"); + projectAdmin.setPermissions(getProjectAdminPermissions(fullList)); + projectAuditor.setPermissions(getProjectAuditorPermissions(fullList)); + projectEditor.setPermissions(getProjectEditorPermissions(fullList)); + projectViewer.setPermissions(getProjectViewerPermissions(fullList)); + + qm.persist(projectAdmin); + qm.persist(projectAuditor); + qm.persist(projectEditor); + qm.persist(projectViewer); + } + } + + private List getProjectAdminPermissions(final List fullList) { + final List permissions = new ArrayList<>(); + for (final Permission permission : fullList) { + if (permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT.name()) || + permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_CREATE.name()) || + permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_READ.name()) || + permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_UPDATE.name()) || + permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_DELETE.name()) || + permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS.name()) || + permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_CREATE.name()) || + permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_READ.name()) || + permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_UPDATE.name()) || + permission.getName().equals(Permissions.POLICY_MANAGEMENT.name()) || + permission.getName().equals(Permissions.POLICY_MANAGEMENT_CREATE.name()) || + permission.getName().equals(Permissions.POLICY_MANAGEMENT_READ.name()) || + permission.getName().equals(Permissions.POLICY_MANAGEMENT_UPDATE.name()) || + permission.getName().equals(Permissions.POLICY_MANAGEMENT_DELETE.name())) { + permissions.add(permission); + } + } + return permissions; + } + + private List getProjectAuditorPermissions(final List fullList) { + final List permissions = new ArrayList<>(); + for (final Permission permission : fullList) { + if (permission.getName().equals(Permissions.VIEW_PORTFOLIO.name()) || + permission.getName().equals(Permissions.VIEW_VULNERABILITY.name()) || + permission.getName().equals(Permissions.VIEW_POLICY_VIOLATION.name()) || + permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_READ.name())) { + permissions.add(permission); + } + } + return permissions; + } + + private List getProjectEditorPermissions(final List fullList) { + final List permissions = new ArrayList<>(); + for (final Permission permission : fullList) { + if (permission.getName().equals(Permissions.BOM_UPLOAD.name()) || + permission.getName().equals(Permissions.VIEW_PORTFOLIO.name()) || + permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_READ.name()) || + permission.getName().equals(Permissions.VIEW_VULNERABILITY.name()) || + permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_READ.name()) || + permission.getName().equals(Permissions.PROJECT_CREATION_UPLOAD.name())) { + permissions.add(permission); + } + } + return permissions; + } + + private List getProjectViewerPermissions(final List fullList) { + final List permissions = new ArrayList<>(); + for (final Permission permission : fullList) { + if (permission.getName().equals(Permissions.VIEW_PORTFOLIO.name()) || + permission.getName().equals(Permissions.VIEW_VULNERABILITY.name()) || + permission.getName().equals(Permissions.VIEW_BADGES.name())) { + permissions.add(permission); + } + } + return permissions; + } + + + /** + * Loads the default repositories + */ + public void loadDefaultRepositories() { + try (QueryManager qm = new QueryManager()) { + LOGGER.info("Synchronizing default repositories to datastore"); + qm.createRepository(RepositoryType.CPAN, "cpan-public-registry", "https://fastapi.metacpan.org/v1/", true, false, false, null, null); + qm.createRepository(RepositoryType.GEM, "rubygems.org", "https://rubygems.org/", true, false, false,null, null); + qm.createRepository(RepositoryType.HEX, "hex.pm", "https://hex.pm/", true, false, false, null, null); + qm.createRepository(RepositoryType.MAVEN, "central", "https://repo1.maven.org/maven2/", true, false, false, null, null); + qm.createRepository(RepositoryType.MAVEN, "atlassian-public", "https://packages.atlassian.com/content/repositories/atlassian-public/", true, false, false, null, null); + qm.createRepository(RepositoryType.MAVEN, "jboss-releases", "https://repository.jboss.org/nexus/content/repositories/releases/", true, false, false, null, null); + qm.createRepository(RepositoryType.MAVEN, "clojars", "https://repo.clojars.org/", true, false, false, null, null); + qm.createRepository(RepositoryType.MAVEN, "google-android", "https://maven.google.com/", true, false, false, null, null); + qm.createRepository(RepositoryType.NPM, "npm-public-registry", "https://registry.npmjs.org/", true, false, false, null, null); + qm.createRepository(RepositoryType.PYPI, "pypi.org", "https://pypi.org/", true, false, false, null, null); + qm.createRepository(RepositoryType.NUGET, "nuget-gallery", "https://api.nuget.org/", true, false, false, null, null); + qm.createRepository(RepositoryType.COMPOSER, "packagist", "https://repo.packagist.org/", true, false, false, null, null); + qm.createRepository(RepositoryType.CARGO, "crates.io", "https://crates.io", true, false, false, null, null); + qm.createRepository(RepositoryType.GO_MODULES, "proxy.golang.org", "https://proxy.golang.org", true, false, false, null, null); + qm.createRepository(RepositoryType.GITHUB, "github.com", "https://github.com", true, false, false, null, null); + qm.createRepository(RepositoryType.HACKAGE, "hackage.haskell", "https://hackage.haskell.org/", true, false, false, null, null); + qm.createRepository(RepositoryType.NIXPKGS, "nixos.org", "https://channels.nixos.org/nixpkgs-unstable/packages.json.br", true, false, false, null, null); + } + } + + /** + * Loads the default ConfigProperty objects + */ + private void loadDefaultConfigProperties() { + try (QueryManager qm = new QueryManager()) { + LOGGER.info("Synchronizing config properties to datastore"); + for (final ConfigPropertyConstants cpc : ConfigPropertyConstants.values()) { + LOGGER.debug("Creating config property: " + cpc.getGroupName() + " / " + cpc.getPropertyName()); + if (qm.getConfigProperty(cpc.getGroupName(), cpc.getPropertyName()) == null) { + qm.createConfigProperty(cpc.getGroupName(), cpc.getPropertyName(), cpc.getDefaultPropertyValue(), cpc.getPropertyType(), cpc.getDescription()); + } + } + } + } + + /** + * Loads the default notification publishers + */ + public void loadDefaultNotificationPublishers() { + try (QueryManager qm = new QueryManager()) { + LOGGER.info("Synchronizing notification publishers to datastore"); + try { + NotificationUtil.loadDefaultNotificationPublishers(qm); + } catch (IOException e) { + LOGGER.error("An error occurred while synchronizing a default notification publisher", e); + } + } + } +} From 53b42cf007e35ad6a7e068a0e0ac5c19a23f39af Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:33:54 -0600 Subject: [PATCH 09/45] fix: add role UUID field (#9) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../java/org/dependencytrack/model/Role.java | 18 ++++++++++++++++++ .../resources/migration/changelog-v5.6.0.xml | 6 ++++++ 2 files changed, 24 insertions(+) diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 8ba1998a6b..47f8516575 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; @@ -34,6 +35,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.UUID; + import javax.jdo.annotations.Column; import javax.jdo.annotations.Element; import javax.jdo.annotations.Extension; @@ -58,6 +61,7 @@ @Persistent(name = "name"), @Persistent(name = "description"), @Persistent(name = "permissions"), + @Persistent(name = "uuid"), }) @JsonInclude(JsonInclude.Include.NON_NULL) public class Role implements Serializable { @@ -101,6 +105,12 @@ public enum FetchGroup { @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "name ASC")) private List permissions; + @Persistent(customValueStrategy = "uuid") + @Unique(name = "ROLE_UUID_IDX") + @Column(name = "UUID", sqlType = "UUID", allowsNull = "false") + @NotNull + private UUID uuid; + public long getId() { return id; } @@ -145,6 +155,14 @@ public void addPermissions(Permission... permissions) { this.permissions.add(permission); } + public UUID getUuid() { + return uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + @Override public String toString() { var permissionStrings = permissions.stream() diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml index caad54dfb6..6398466d0a 100644 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -678,6 +678,12 @@ + + + +
From 9959ada177f87350cfe1db6122fe14852b6d15bc Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:52:25 -0600 Subject: [PATCH 10/45] refactor: implement role endpoint methods (#10) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../persistence/QueryManager.java | 16 +-- .../persistence/jdbi/RoleDao.java | 36 ++++++ .../resources/v1/RoleResource.java | 93 ++++++++++----- .../resources/v1/UserResource.java | 71 +++++++---- .../persistence/RoleQueryManager.java | 111 ++++++++++++++++++ 5 files changed, 263 insertions(+), 64 deletions(-) create mode 100644 apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java create mode 100644 src/main/java/org/dependencytrack/persistence/RoleQueryManager.java diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index bdc24828aa..f667f7acaf 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -857,12 +857,8 @@ public Role getRole(String uuid) { return getRoleQueryManager().getRole(null); } - public Role updateRole(Role role) { - return getRoleQueryManager().updateRole(role); - } - - public boolean deleteRole(String uuid, boolean value) { - return getRoleQueryManager().deleteRole(uuid, value); + public Role updateRole(Role transientRole) { + return getRoleQueryManager().updateRole(transientRole); } public Vulnerability createVulnerability(Vulnerability vulnerability, boolean commitIndex) { @@ -1108,12 +1104,12 @@ public synchronized RepositoryMetaComponent synchronizeRepositoryMetaComponent(f return getRepositoryQueryManager().synchronizeRepositoryMetaComponent(transientRepositoryMetaComponent); } - public boolean addRoleToUser(UserPrincipal principal, Role role, String roleName, String projectName){ - return getRoleQueryManager().addRoleToUser(principal, role, roleName, projectName); + public boolean addRoleToUser(UserPrincipal principal, Role role, Project project){ + return getRoleQueryManager().addRoleToUser(principal, role, project); } - public boolean removeRoleFromUser(UserPrincipal principal, Role role, String roleName, String projectName){ - return getRoleQueryManager().removeRoleFromUser(principal, role, roleName, projectName); + public boolean removeRoleFromUser(UserPrincipal principal, Role role, Project project){ + return getRoleQueryManager().removeRoleFromUser(principal, role, project); } public NotificationRule createNotificationRule(String name, NotificationScope scope, NotificationLevel level, NotificationPublisher publisher) { diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java new file mode 100644 index 0000000000..c64a25de4e --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -0,0 +1,36 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence.jdbi; + +import org.jdbi.v3.sqlobject.customizer.Bind; +import org.jdbi.v3.sqlobject.statement.SqlUpdate; + +/** + * @since 5.6.0 + */ +public interface RoleDao { + + @SqlUpdate(""" + DELETE + FROM "ROLE" + WHERE "ID" = :roleId + """) + int deleteRole(@Bind final long roleId); + +} diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index 34eada7cc3..029c38ef68 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -50,9 +50,11 @@ import org.dependencytrack.auth.Permissions; import org.dependencytrack.model.validation.ValidUuid; import org.dependencytrack.persistence.QueryManager; +import org.dependencytrack.persistence.jdbi.RoleDao; +import org.jdbi.v3.core.Handle; import org.owasp.security.logging.SecurityMarkers; -import java.util.List; +import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; /** * JAX-RS resources for processing roles. @@ -74,44 +76,52 @@ public class RoleResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all roles", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

" - ) + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

") @ApiResponses(value = { @ApiResponse( responseCode = "200", description = "A list of all roles", - headers = @Header(name = TOTAL_COUNT_HEADER, description = "The total number of roles", schema = @Schema(format = "integer")), - content = @Content(array = @ArraySchema(schema = @Schema(implementation = Role.class))) - ), + headers = @Header( + name = TOTAL_COUNT_HEADER, + description = "The total number of roles", + schema = @Schema(format = "integer")), + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Role.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_READ}) public Response getRoles() { - return Response.ok(roles).header(TOTAL_COUNT_HEADER, totalCount).build(); + try (QueryManager qm = new QueryManager()) { + return Response.ok(qm.getRoles()).header(TOTAL_COUNT_HEADER, qm.getCount(Role.class)).build(); } + } @GET @Path("/{uuid}") @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a specific role", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

" - ) + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

") @ApiResponses(value = { @ApiResponse( responseCode = "200", description = "A specific role", - content = @Content(schema = @Schema(implementation = Role.class)) - ), + content = @Content(schema = @Schema(implementation = Role.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_READ}) public Response getRole( - @Parameter(description = "The UUID of the role to retrieve", schema = @Schema(type = "string", format = "uuid"), required = true) - @PathParam("uuid") @ValidUuid String uuid) { - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Returned role: " + role.getName()); - return Response.ok(role).build(); + @Parameter( + description = "The UUID of the role to retrieve", + schema = @Schema(type = "string", format = "uuid"), + required = true) @PathParam("uuid") @ValidUuid String uuid) { + try (QueryManager qm = new QueryManager()) { + Role role = qm.getObjectByUuid(Role.class, uuid); + if (role == null) + return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + + return Response.ok(role).build(); + } } @PUT @@ -119,20 +129,24 @@ public Response getRole( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new role", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_CREATE

" - ) + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_CREATE

") @ApiResponses(value = { @ApiResponse( responseCode = "201", description = "The created role", - content = @Content(schema = @Schema(implementation = Role.class)) - ), + content = @Content(schema = @Schema(implementation = Role.class))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_CREATE}) public Response createRole(Role jsonRole) { - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Created role: " + role.getName()); - return Response.ok(role).build(); + failOnValidationError(super.getValidator().validateProperty(jsonRole, "name")); + + try (QueryManager qm = new QueryManager()) { + final Role role = qm.createRole(jsonRole.getName(), jsonRole.getDescription(), jsonRole.getPermissions()); + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Role created: " + role.getName()); + + return Response.status(Response.Status.CREATED).entity(role).build(); + } } @POST @@ -140,21 +154,28 @@ public Response createRole(Role jsonRole) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a role's fields", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_UPDATE

" - ) + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_UPDATE

") @ApiResponses(value = { @ApiResponse( responseCode = "200", description = "The updated role", - content = @Content(schema = @Schema(implementation = Role.class)) - ), + content = @Content(schema = @Schema(implementation = Role.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_UPDATE}) public Response updateRole(Role jsonRole) { - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Updated role: " + role.getName()); - return Response.ok(role).build(); + failOnValidationError(super.getValidator().validateProperty(jsonRole, "name")); + + try (QueryManager qm = new QueryManager()) { + Role role = qm.updateRole(jsonRole); + if (role == null) + return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Role updated: " + role.getName()); + + return Response.ok(role).build(); + } } @DELETE @@ -162,8 +183,7 @@ public Response updateRole(Role jsonRole) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a role", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_DELETE

" - ) + description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_DELETE

") @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Role removed successfully"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @@ -171,8 +191,19 @@ public Response updateRole(Role jsonRole) { }) @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_DELETE}) public Response deleteRole(Role jsonRole) { - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Delete role: " + role.getName()); - return Response.ok(role).build(); + try (QueryManager qm = new QueryManager()) { + final Role role = qm.getObjectByUuid(Role.class, jsonRole.getUuid(), Role.FetchGroup.ALL.name()); + if (role == null) + return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + + try (final Handle jdbiHandle = openJdbiHandle()) { + jdbiHandle.attach(RoleDao.class).deleteRole(role.getId()); + } + + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Role deleted: " + role.getName()); + + return Response.noContent().build(); + } } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 3f797283ff..c0ece5e810 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -26,6 +26,7 @@ import org.dependencytrack.auth.Permissions; import org.dependencytrack.event.kafka.KafkaEventDispatcher; import org.dependencytrack.model.IdentifiableObject; +import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; import org.dependencytrack.notification.NotificationConstants; import org.dependencytrack.notification.NotificationGroup; @@ -876,13 +877,19 @@ private UserSubject buildUserSubject(final String username, final String email) @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response addRoleToUser( @Parameter(description = "A valid username", required = true) - @PathParam("username") String username, + @PathParam("username") + String username, + @Parameter(description = "The UUID of the role to associate username with", required = true) - IdentifiableObject identifiableObject, - @Parameter(description = "The name of the role", required = true) - @QueryParam("roleName") String roleName, + IdentifiableObject identifiableObject, + @Parameter(description = "The name of the project", required = true) - @QueryParam("projectName") String projectName) { + @QueryParam("projectName") + String projectName, + + @Parameter(description = "The version of the project") + @QueryParam("projectVersion") + String projectVersion) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, identifiableObject.getUuid()); if (role == null) @@ -892,14 +899,20 @@ public Response addRoleToUser( if (principal == null) return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); - final boolean modified = qm.addRoleToUser(principal, role, roleName, projectName); + Project project = qm.getProject(projectName, projectVersion); + if (project == null) + return Response.status(Response.Status.NOT_FOUND).entity("The project could not be found.").build(); + + final boolean modified = qm.addRoleToUser(principal, role, project); + if (!modified) + return Response.notModified().entity("The user is already a member of the specified role.").build(); + principal = qm.getObjectById(principal.getClass(), principal.getId()); - if (modified) { - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added role membership for: %s / role: %s / project: %s".formatted(principal.getName(), role.getName(), projectName)); - return Response.ok(principal).build(); - } + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, + "Added role membership for: %s / role: %s / project: %s" + .formatted(principal.getName(), role.getName(), projectName)); - return Response.status(Response.Status.NOT_MODIFIED).entity("The user is already a member of the specified role.").build(); + return Response.ok(principal).build(); } } @@ -925,13 +938,19 @@ public Response addRoleToUser( @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response removeRoleFromUser( @Parameter(description = "A valid username", required = true) - @PathParam("username") String username, - @Parameter(description = "The UUID of the role to remove from the username", required = true) - IdentifiableObject identifiableObject, - @Parameter(description = "The name of the role", required = true) - @QueryParam("roleName") String roleName, + @PathParam("username") + String username, + + @Parameter(description = "The UUID of the role to associate username with", required = true) + IdentifiableObject identifiableObject, + @Parameter(description = "The name of the project", required = true) - @QueryParam("projectName") String projectName) { + @QueryParam("projectName") + String projectName, + + @Parameter(description = "The version of the project") + @QueryParam("projectVersion") + String projectVersion) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, identifiableObject.getUuid()); if (role == null) @@ -941,15 +960,21 @@ public Response removeRoleFromUser( if (principal == null) return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); - final boolean modified = qm.removeRoleFromUser(principal, role, roleName, projectName); + Project project = qm.getProject(projectName, projectVersion); + if (project == null) + return Response.status(Response.Status.NOT_FOUND).entity("The project could not be found.").build(); + + final boolean modified = qm.removeRoleFromUser(principal, role, project); + if (!modified) + return Response.notModified().entity("The user is not a member of the specified role.").build(); principal = qm.getObjectById(principal.getClass(), principal.getId()); - if (modified) { - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Removed role membership for: %s / role: %s / project: %s".formatted(principal.getName(), role.getName(), projectName)); - return Response.noContent().build(); - } + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, + "Removed role membership for: %s / role: %s / project: %s" + .formatted(principal.getName(), role.getName(), projectName)); - return Response.status(Response.Status.NOT_MODIFIED).entity("The user is not a member of the specified role.").build(); + return Response.noContent().build(); } } + } diff --git a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java new file mode 100644 index 0000000000..9681746ad2 --- /dev/null +++ b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -0,0 +1,111 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence; + +import java.util.Collections; +import java.util.List; + +import javax.jdo.PersistenceManager; +import javax.jdo.Query; + +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Role; + +import alpine.common.logging.Logger; +import alpine.model.Permission; +import alpine.model.UserPrincipal; +import alpine.resources.AlpineRequest; + +final class RoleQueryManager extends QueryManager implements IQueryManager { + + private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); + + RoleQueryManager(final PersistenceManager pm) { + super(pm); + } + + RoleQueryManager(final PersistenceManager pm, final AlpineRequest request) { + super(pm, request); + } + + @Override + public Role createRole(final String name, final String description, final List permissions) { + Role role = new Role(); + role.setName(name); + role.setDescription(description); + role.setPermissions(permissions); + + return persist(role); + } + + @Override + public List getRoles() { + final Query query = pm.newQuery(Role.class); + if (orderBy == null) + query.setOrdering("name asc"); + + return query.executeList(); + } + + @Override + public Role getRole(String uuid) { + final Query query = pm.newQuery(Role.class, "uuid == :uuid"); + + return query.executeUnique(); + } + + public List getUnassignedProjects(final String username) { + return getUnassignedProjects(getUserPrincipal(username)); + } + + public List getUnassignedProjects(final UserPrincipal principal) { + // TODO: Implement getUnassignedProjects + return Collections.emptyList(); + } + + public List getUnassignedRolePermissions(final Role role) { + // TODO: Implement getUnassignedRolePermissions + return Collections.emptyList(); + } + + @Override + public Role updateRole(Role transientRole) { + final Role role = getObjectByUuid(Role.class, transientRole.getUuid()); + if (role == null) + return null; + + role.setName(transientRole.getName()); + role.setDescription(transientRole.getDescription()); + + return persist(role); + } + + @Override + public boolean addRoleToUser(UserPrincipal user, Role role, Project project) { + // TODO: Implement addRoleToUser + return true; + } + + @Override + public boolean removeRoleFromUser(UserPrincipal principal, Role role, Project project) { + // TODO: Implement removeRoleFromUser + return true; + } + +} From 1a0cc70e87ef97c656d44e3113a07bda9268f6d9 Mon Sep 17 00:00:00 2001 From: lmphil <126618132+lmphil@users.noreply.github.com> Date: Sat, 29 Mar 2025 18:35:06 -0400 Subject: [PATCH 11/45] feat: get user project permissions (wip) (#11) Signed-off-by: lmphil <126618132+lmphil@users.noreply.github.com> --- .../persistence/RoleQueryManagerTest.java | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java new file mode 100644 index 0000000000..c59227b733 --- /dev/null +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -0,0 +1,171 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence; + +import org.dependencytrack.model.Project; +import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.ProjectRole.LdapUserProjectRole; +import org.dependencytrack.model.ProjectRole.ManagedUserProjectRole; +import org.dependencytrack.model.ProjectRole.OidcUserProjectRole; +import org.dependencytrack.model.Role; +import org.jdbi.v3.core.Jdbi; + +import alpine.Config; +import alpine.model.ManagedUser; +import alpine.model.Permission; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.dependencytrack.PersistenceCapableTest; +import org.dependencytrack.common.ConfigKey; +import org.dependencytrack.event.kafka.KafkaProducerInitializer; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.utility.DockerImageName; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; + +public class RoleQueryManagerTest extends PersistenceCapableTest { + + private PostgreSQLContainer postgresContainer; + private Jdbi jdbi; + + @Before + public void setUp() { + System.setProperty("javax.jdo.PersistenceManagerFactoryClass", + "org.datanucleus.api.jdo.JDOPersistenceManagerFactory"); + + postgresContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:11-alpine")); + postgresContainer.start(); + + jdbi = Jdbi.create( + postgresContainer.getJdbcUrl(), + postgresContainer.getUsername(), + postgresContainer.getPassword()); + } + + @After + public void tearDown() { + if (postgresContainer != null) { + postgresContainer.stop(); + } + } + + // @BeforeClass + // public static void beforeClass() { + // Config.enableUnitTests(); + // } + + // @AfterClass + // public static void afterClass() { + // KafkaProducerInitializer.tearDown(); + // } + + // @Rule + // public WireMockRule wireMockRule = new WireMockRule(); + + @Test + public void testGetUserProjectPermissions() throws ParseException { + final var configMock = mock(Config.class); + when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_URL))).thenReturn(postgresContainer.getJdbcUrl()); + when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_DRIVER))) + .thenReturn(postgresContainer.getDriverClassName()); + when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_USERNAME))) + .thenReturn(postgresContainer.getUsername()); + when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_PASSWORD))) + .thenReturn(postgresContainer.getPassword()); + when(configMock.getPropertyAsBoolean(eq(ConfigKey.INIT_TASKS_ENABLED))).thenReturn(true); + when(configMock.getPropertyAsBoolean(eq(ConfigKey.DATABASE_RUN_MIGRATIONS))).thenReturn(true); + + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var readPermission = new Permission(); + readPermission.setId(1); + readPermission.setName("read"); + readPermission.setDescription("permission to read"); + qm.persist(readPermission); + + final var writePermission = new Permission(); + writePermission.setId(2); + writePermission.setName("write"); + writePermission.setDescription("permission to write"); + qm.persist(writePermission); + + List expectedPermissionsList = Arrays.asList( + readPermission, + writePermission); + + Set expectedPermissions = new HashSet<>(expectedPermissionsList); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + qm.persist(testUser); + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + maintainerRole.setPermissions(expectedPermissions); + qm.persist(maintainerRole); + + // final var ldapUserProjectRole = new LdapUserProjectRole(); + // ldapUserProjectRole.setProject(testProject); + + final var managedUserProjectRole = new ManagedUserProjectRole(); + // managedUserProjectRole.setId(1); + managedUserProjectRole.setProject(testProject); + managedUserProjectRole.setManagedUsers(Arrays.asList(testUser)); + managedUserProjectRole.setRole(maintainerRole); + // qm.persist(managedUserProjectRole); + + // final var oidcUserProjectRole = new OidcUserProjectRole(); + + List actualPermissions = qm.getUserProjectPermissions("test-user", "test-project"); + + Assert.assertEquals(actualPermissions, expectedPermissionsList); + } + +} From 07aedbe73bd84989a9b64083516b86b7841992e4 Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Tue, 4 Mar 2025 12:29:35 -0600 Subject: [PATCH 12/45] refactor: implement adding/removing users to/from roles (#13) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../persistence/jdbi/RoleDao.java | 38 ++++++++- .../persistence/RoleQueryManager.java | 78 +++++++++++++++++-- 2 files changed, 110 insertions(+), 6 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java index c64a25de4e..0ce3d1ac77 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -26,11 +26,47 @@ */ public interface RoleDao { - @SqlUpdate(""" + @SqlUpdate(/* language=sql */ """ DELETE FROM "ROLE" WHERE "ID" = :roleId """) int deleteRole(@Bind final long roleId); + @SqlUpdate(/* language=sql */ """ + DELETE + FROM "LDAPUSERS_PROJECTS_ROLES" + WHERE "LDAPUSER_ID" = :userId + AND "PROJECT_ACCESS_ROLE_ID" IN ( + SELECT "ID" + FROM "PROJECT_ACCESS_ROLES" + WHERE "ROLE_ID" = :roleId + AND "PROJECT_ID" = :projectId) + """) + int removeRoleFromLdapUser(@Bind final long userId, @Bind final long projectId, @Bind final long roleId); + + @SqlUpdate(/* language=sql */ """ + DELETE + FROM "MANAGEDUSERS_PROJECTS_ROLES" + WHERE "MANAGEDUSER_ID" = :userId + AND "PROJECT_ACCESS_ROLE_ID" IN ( + SELECT "ID" + FROM "PROJECT_ACCESS_ROLES" + WHERE "ROLE_ID" = :roleId + AND "PROJECT_ID" = :projectId) + """) + int removeRoleFromManagedUser(@Bind final long userId, @Bind final long projectId, @Bind final long roleId); + + @SqlUpdate(/* language=sql */ """ + DELETE + FROM "OIDCUSERS_PROJECTS_ROLES" + WHERE "OIDCUSER_ID" = :userId + AND "PROJECT_ACCESS_ROLE_ID" IN ( + SELECT "ID" + FROM "PROJECT_ACCESS_ROLES" + WHERE "ROLE_ID" = :roleId + AND "PROJECT_ID" = :projectId) + """) + int removeRoleFromOidcUser(@Bind final long userId, @Bind final long projectId, @Bind final long roleId); + } diff --git a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 9681746ad2..4fae8ce2f8 100644 --- a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -18,20 +18,30 @@ */ package org.dependencytrack.persistence; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.jdo.PersistenceManager; import javax.jdo.Query; +import org.dependencytrack.model.MappedRole; import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; +import org.dependencytrack.persistence.jdbi.RoleDao; +import org.jdbi.v3.core.Handle; import alpine.common.logging.Logger; +import alpine.model.LdapUser; +import alpine.model.ManagedUser; +import alpine.model.OidcUser; import alpine.model.Permission; import alpine.model.UserPrincipal; import alpine.resources.AlpineRequest; +import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; + final class RoleQueryManager extends QueryManager implements IQueryManager { private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); @@ -98,14 +108,72 @@ public Role updateRole(Role transientRole) { @Override public boolean addRoleToUser(UserPrincipal user, Role role, Project project) { - // TODO: Implement addRoleToUser - return true; + Query query = pm.newQuery(MappedRole.class) + .filter("project.id == :projectId && role.id == :roleId") + .setNamedParameters(Map.of( + "roleId", role.getId(), + "projectId", project.getId())); + + try { + query.getFetchPlan().setGroup(MappedRole.FetchGroup.ALL.name()); + MappedRole result = query.executeUnique(); + + if (result == null) { + LOGGER.info("Creating role mapping for project: %s / role: %s" + .formatted(project.getName(), role.getName())); + + result = new MappedRole(); + result.setProject(project); + result.setRole(role); + } + + result.setLdapUsers(result.getLdapUsers() != null ? result.getLdapUsers() : new ArrayList<>()); + result.setManagedUsers(result.getManagedUsers() != null ? result.getManagedUsers() : new ArrayList<>()); + result.setOidcUsers(result.getOidcUsers() != null ? result.getOidcUsers() : new ArrayList<>()); + + final MappedRole mappedRole = result; + + boolean modified = switch (user) { + case LdapUser ldapUser when !mappedRole.getLdapUsers().contains(ldapUser) -> { + mappedRole.addLdapUsers(ldapUser); + yield true; + } + case ManagedUser managedUser when !mappedRole.getManagedUsers().contains(managedUser) -> { + mappedRole.addManagedUsers(managedUser); + yield true; + } + case OidcUser oidcUser when !mappedRole.getOidcUsers().contains(oidcUser) -> { + mappedRole.addOidcUsers(oidcUser); + yield true; + } + default -> false; + }; + + if (modified) + persist(mappedRole); + + return modified; + } finally { + query.closeAll(); + } } @Override - public boolean removeRoleFromUser(UserPrincipal principal, Role role, Project project) { - // TODO: Implement removeRoleFromUser - return true; + public boolean removeRoleFromUser(UserPrincipal user, Role role, Project project) { + try (final Handle jdbiHandle = openJdbiHandle()) { + int count = switch (user) { + case LdapUser ldapUser -> jdbiHandle.attach(RoleDao.class) + .removeRoleFromLdapUser(ldapUser.getId(), project.getId(), role.getId()); + case ManagedUser managedUser -> jdbiHandle.attach(RoleDao.class) + .removeRoleFromManagedUser(managedUser.getId(), project.getId(), role.getId()); + case OidcUser oidcUser -> jdbiHandle.attach(RoleDao.class) + .removeRoleFromOidcUser(oidcUser.getId(), project.getId(), role.getId()); + default -> 0; + }; + + return count == 1; + } + } } From 68cd5a887c9a642dba83fc9d45b1c5b149c74911 Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Mon, 17 Mar 2025 14:34:16 -0500 Subject: [PATCH 13/45] refactor: flatten user role join tables (#14) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../org/dependencytrack/model/MappedRole.java | 200 --------------- .../dependencytrack/model/ProjectRole.java | 234 ++++++++++++++++++ .../persistence/QueryManager.java | 80 ++++-- .../jdbi/mapping/ProjectRoleRowMapper.java | 65 +++++ .../resources/v1/AccessControlResource.java | 47 ++++ .../main/resources/META-INF/persistence.xml | 6 +- .../persistence/RoleQueryManager.java | 100 ++------ .../persistence/jdbi/RoleDao.java | 112 +++++++++ .../resources/migration/changelog-v5.6.0.xml | 122 ++++----- .../function_has-project-access.sql | 54 ++++ 10 files changed, 673 insertions(+), 347 deletions(-) delete mode 100644 apiserver/src/main/java/org/dependencytrack/model/MappedRole.java create mode 100644 apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java create mode 100644 apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java create mode 100644 src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java create mode 100644 src/main/resources/migration/procedures/function_has-project-access.sql diff --git a/apiserver/src/main/java/org/dependencytrack/model/MappedRole.java b/apiserver/src/main/java/org/dependencytrack/model/MappedRole.java deleted file mode 100644 index 6480e4f9a2..0000000000 --- a/apiserver/src/main/java/org/dependencytrack/model/MappedRole.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.model; - -import alpine.model.LdapUser; -import alpine.model.ManagedUser; -import alpine.model.OidcUser; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonInclude; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.jdo.annotations.Column; -import javax.jdo.annotations.Element; -import javax.jdo.annotations.Extension; -import javax.jdo.annotations.FetchGroup; -import javax.jdo.annotations.IdGeneratorStrategy; -import javax.jdo.annotations.Join; -import javax.jdo.annotations.Order; -import javax.jdo.annotations.PersistenceCapable; -import javax.jdo.annotations.Persistent; -import javax.jdo.annotations.PrimaryKey; -import javax.jdo.annotations.Unique; - -/** - * Model for associating a role on a given project with users. - * - * @author Allen Shearin - * @since 5.6.0 - */ -@PersistenceCapable(table = "PROJECT_ACCESS_ROLES") -@Unique(name = "LDAPUSERS_PROJECTS_ROLES_COMPOSITE_IDX", - table = "LDAPUSERS_PROJECTS_ROLES", - members = { "ldapUsers", "project", "role" }, - deferred = "true") -@Unique(name = "MANAGEDUSERS_PROJECTS_ROLES_COMPOSITE_IDX", - table = "MANAGEDUSERS_PROJECTS_ROLES", - members = { "managedUsers", "project", "role" }, - deferred = "true") -@Unique(name = "OIDCUSERS_PROJECTS_ROLES_COMPOSITE_IDX", - table = "OIDCUSERS_PROJECTS_ROLES", - members = { "oidcUsers", "project", "role" }, - deferred = "true") -@FetchGroup(name = "ALL", members = { - @Persistent(name = "role"), - @Persistent(name = "project"), - @Persistent(name = "ldapUsers"), - @Persistent(name = "managedUsers"), - @Persistent(name = "oidcUsers") -}) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class MappedRole implements Serializable { - - private static final long serialVersionUID = 1982348710987098723L; - - /** - * Defines JDO fetch groups for this class. - */ - public enum FetchGroup { - ALL - } - - @PrimaryKey - @Persistent(valueStrategy = IdGeneratorStrategy.NATIVE) - @JsonIgnore - private long id; - - @Persistent - @Column(name = "ROLE_ID", allowsNull = "false") - @JsonIgnore - private Role role; - - @Persistent - @Column(name = "PROJECT_ID", allowsNull = "false") - @JsonIgnore - private Project project; - - @Persistent(table = "LDAPUSERS_PROJECTS_ROLES", defaultFetchGroup = "true") - @Join(column = "PROJECT_ACCESS_ROLE_ID") - @Element(column = "LDAPUSER_ID") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - private List ldapUsers; - - @Persistent(table = "MANAGEDUSERS_PROJECTS_ROLES") - @Join(column = "PROJECT_ACCESS_ROLE_ID") - @Element(column = "MANAGEDUSER_ID") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - private List managedUsers; - - @Persistent(table = "OIDCUSERS_PROJECTS_ROLES") - @Join(column = "PROJECT_ACCESS_ROLE_ID") - @Element(column = "OIDCUSER_ID") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - private List oidcUsers; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public Role getRole() { - return role; - } - - public void setRole(Role role) { - this.role = role; - } - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - public List getLdapUsers() { - return ldapUsers; - } - - public void setLdapUsers(List ldapUsers) { - this.ldapUsers = ldapUsers; - } - - public void addLdapUsers(LdapUser... ldapUsers) { - if (this.ldapUsers == null) { - this.ldapUsers = new ArrayList<>(Arrays.asList(ldapUsers)); - - return; - } - - for (var user : ldapUsers) - if (!this.ldapUsers.contains(user)) - this.ldapUsers.add(user); - } - - public List getManagedUsers() { - return managedUsers; - } - - public void setManagedUsers(List managedUsers) { - this.managedUsers = managedUsers; - } - - public void addManagedUsers(ManagedUser... managedUsers) { - if (this.managedUsers == null) { - this.managedUsers = new ArrayList<>(Arrays.asList(managedUsers)); - - return; - } - - for (var user : managedUsers) - if (!this.managedUsers.contains(user)) - this.managedUsers.add(user); - } - - public List getOidcUsers() { - return oidcUsers; - } - - public void setOidcUsers(List oidcUsers) { - this.oidcUsers = oidcUsers; - } - - public void addOidcUsers(OidcUser... oidcUsers) { - if (this.oidcUsers == null) { - this.oidcUsers = new ArrayList<>(Arrays.asList(oidcUsers)); - - return; - } - - for (var user : oidcUsers) - if (!this.oidcUsers.contains(user)) - this.oidcUsers.add(user); - } - -} \ No newline at end of file diff --git a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java new file mode 100644 index 0000000000..dbf4807603 --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java @@ -0,0 +1,234 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; + +import alpine.model.LdapUser; +import alpine.model.ManagedUser; +import alpine.model.OidcUser; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + +import javax.jdo.annotations.Column; +import javax.jdo.annotations.Extension; +import javax.jdo.annotations.FetchGroup; +import javax.jdo.annotations.Order; +import javax.jdo.annotations.PersistenceAware; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.Unique; + +/** + * Base class for user-project-role mapping. + * + * @author Jonathan Howard + * @since 5.6.0 + */ +@PersistenceAware +@JsonInclude(JsonInclude.Include.NON_NULL) +public abstract class ProjectRole implements Serializable { + + @Persistent(defaultFetchGroup = "true") + @Column(name = "ROLE_ID", allowsNull = "false") + @JsonIgnore + private Role role; + + @Persistent(defaultFetchGroup = "true") + @Column(name = "PROJECT_ID", allowsNull = "false") + @JsonIgnore + private Project project; + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public Project getProject() { + return project; + } + + public void setProject(Project project) { + this.project = project; + } + + /** + * Model for associating a role on a given project with LDAP users. + * + * @author Allen Shearin + * @since 5.6.0 + */ + @PersistenceCapable(table = "LDAPUSERS_PROJECTS_ROLES") + @Unique(name = "LDAPUSERS_PROJECTS_ROLES_COMPOSITE_IDX", + table = "LDAPUSERS_PROJECTS_ROLES", + members = { "ldapUsers", "project", "role" }, + deferred = "true") + @FetchGroup(name = "ALL", members = { + @Persistent(name = "role"), + @Persistent(name = "project"), + @Persistent(name = "ldapUsers") + }) + @JsonInclude(JsonInclude.Include.NON_NULL) + public static class LdapUserProjectRole extends ProjectRole { + + private static final long serialVersionUID = 6018553054343647649L; + + /** + * Defines JDO fetch groups for this class. + */ + public enum FetchGroup { + ALL + } + + @Persistent(defaultFetchGroup = "true") + @Column(name = "LDAPUSER_ID", allowsNull = "false") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + private List ldapUsers; + + public List getLdapUsers() { + return ldapUsers; + } + + public void setLdapUsers(List ldapUsers) { + this.ldapUsers = ldapUsers; + } + + public void addLdapUsers(LdapUser... ldapUsers) { + this.ldapUsers = Objects.requireNonNullElse(this.ldapUsers, new ArrayList()); + this.ldapUsers = Stream.concat(this.ldapUsers.stream(), Arrays.stream(ldapUsers)) + .distinct() + .sorted(Comparator.comparing(LdapUser::getUsername)) + .toList(); + } + + } + + /** + * Model for associating a role on a given project with managed users. + * + * @author Allen Shearin + * @since 5.6.0 + */ + @PersistenceCapable(table = "MANAGEDUSERS_PROJECTS_ROLES") + @Unique(name = "MANAGEDUSERS_PROJECTS_ROLES_COMPOSITE_IDX", + table = "MANAGEDUSERS_PROJECTS_ROLES", + members = { "managedUsers", "project", "role" }, + deferred = "true") + @FetchGroup(name = "ALL", members = { + @Persistent(name = "role"), + @Persistent(name = "project"), + @Persistent(name = "managedUsers") + }) + @JsonInclude(JsonInclude.Include.NON_NULL) + public static class ManagedUserProjectRole extends ProjectRole { + + private static final long serialVersionUID = -380122087527236991L; + + /** + * Defines JDO fetch groups for this class. + */ + public enum FetchGroup { + ALL + } + + @Persistent(defaultFetchGroup = "true") + @Column(name = "MANAGEDUSER_ID", allowsNull = "false") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + private List managedUsers; + + public List getManagedUsers() { + return managedUsers; + } + + public void setManagedUsers(List managedUsers) { + this.managedUsers = managedUsers; + } + + public void addManagedUsers(ManagedUser... managedUsers) { + this.managedUsers = Objects.requireNonNullElse(this.managedUsers, new ArrayList()); + this.managedUsers = Stream.concat(this.managedUsers.stream(), Arrays.stream(managedUsers)) + .distinct() + .sorted(Comparator.comparing(ManagedUser::getUsername)) + .toList(); + } + + } + + /** + * Model for associating a role on a given project with OIDC users. + * + * @author Allen Shearin + * @since 5.6.0 + */ + @PersistenceCapable(table = "OIDCUSERS_PROJECTS_ROLES") + @Unique(name = "OIDCUSERS_PROJECTS_ROLES_COMPOSITE_IDX", + table = "OIDCUSERS_PROJECTS_ROLES", + members = { "oidcUsers", "project", "role" }, + deferred = "true") + @FetchGroup(name = "ALL", members = { + @Persistent(name = "role"), + @Persistent(name = "project"), + @Persistent(name = "oidcUsers") + }) + @JsonInclude(JsonInclude.Include.NON_NULL) + public static class OidcUserProjectRole extends ProjectRole { + + private static final long serialVersionUID = -5029209056240375886L; + + /** + * Defines JDO fetch groups for this class. + */ + public enum FetchGroup { + ALL + } + + @Persistent(defaultFetchGroup = "true") + @Column(name = "OIDCUSER_ID", allowsNull = "false") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + private List oidcUsers; + + public List getOidcUsers() { + return oidcUsers; + } + + public void setOidcUsers(List oidcUsers) { + this.oidcUsers = oidcUsers; + } + + public void addOidcUsers(OidcUser... oidcUsers) { + this.oidcUsers = Objects.requireNonNullElse(this.oidcUsers, new ArrayList()); + this.oidcUsers = Stream.concat(this.oidcUsers.stream(), Arrays.stream(oidcUsers)) + .distinct() + .sorted(Comparator.comparing(OidcUser::getUsername)) + .toList(); + } + + } + +} diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index f667f7acaf..915bd9d8e1 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -23,6 +23,9 @@ import alpine.common.validation.RegexSequence; import alpine.model.ApiKey; import alpine.model.ConfigProperty; +import alpine.model.LdapUser; +import alpine.model.ManagedUser; +import alpine.model.OidcUser; import alpine.model.IConfigProperty.PropertyType; import alpine.model.Permission; import alpine.model.Team; @@ -478,25 +481,56 @@ public QueryManager withL2CacheDisabled() { return this; } + /** + * Get the IDs of the {@link ProjectRole}s a given {@link Principal} is a member of. + * + * @return A {@link Set} of {@link ProjectRole} IDs + */ + protected Set getRoleIds(final Principal principal, final Project project) { + String usersField; + Class cls; + + switch (principal) { + case LdapUser ldapUser -> { + usersField = "ldapUsers"; + cls = ProjectRole.LdapUserProjectRole.class; + } + case ManagedUser managedUser -> { + usersField = "managedUsers"; + cls = ProjectRole.ManagedUserProjectRole.class; + } + case OidcUser oidcUser -> { + usersField = "oidcUsers"; + cls = ProjectRole.OidcUserProjectRole.class; + } + default -> { + return Collections.emptySet(); + } + }; + + Query query = pm.newQuery(cls) + .filter("project.id == :projectId && %s.contains(:principal)".formatted(usersField)) + .setNamedParameters(Map.ofEntries( + Map.entry("principal", principal), + Map.entry("projectId", project.getId()))); + + return Set.of(executeAndCloseList(query).stream() + .map(ProjectRole::getRole) + .map(Role::getId) + .toArray(Long[]::new)); + } + /** * Get the IDs of the {@link Team}s a given {@link Principal} is a member of. * * @return A {@link Set} of {@link Team} IDs */ protected Set getTeamIds(final Principal principal) { - final var principalTeamIds = new HashSet(); - if (principal instanceof final User user - && user.getTeams() != null) { - for (final Team userInTeam : user.getTeams()) { - principalTeamIds.add(userInTeam.getId()); - } - } else if (principal instanceof final ApiKey apiKey - && apiKey.getTeams() != null) { - for (final Team userInTeam : apiKey.getTeams()) { - principalTeamIds.add(userInTeam.getId()); - } - } - return principalTeamIds; + return switch (principal) { + case UserPrincipal userPrincipal -> Set.of(userPrincipal.getTeams().toArray(Long[]::new)); + case ApiKey apiKey -> Set.of(apiKey.getTeams().toArray(Long[]::new)); + default -> Collections.emptySet(); + }; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1108,8 +1142,24 @@ public boolean addRoleToUser(UserPrincipal principal, Role role, Project project return getRoleQueryManager().addRoleToUser(principal, role, project); } - public boolean removeRoleFromUser(UserPrincipal principal, Role role, Project project){ - return getRoleQueryManager().removeRoleFromUser(principal, role, project); + public List getUnassignedProjects(final String username) { + return getRoleQueryManager().getUnassignedProjects(username); + } + + public List getUnassignedProjects(final UserPrincipal user) { + return getRoleQueryManager().getUnassignedProjects(user); + } + + public List getUnassignedRolePermissions(final Role role) { + return getRoleQueryManager().getUnassignedRolePermissions(role); + } + + public List getUserRoles(UserPrincipal user) { + return getRoleQueryManager().getUserRoles(user); + } + + public boolean removeRoleFromUser(UserPrincipal user, Role role, Project project) { + return getRoleQueryManager().removeRoleFromUser(user, role, project); } public NotificationRule createNotificationRule(String name, NotificationScope scope, NotificationLevel level, NotificationPublisher publisher) { diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java new file mode 100644 index 0000000000..d71d0bfdbe --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java @@ -0,0 +1,65 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence.jdbi.mapping; + +import org.dependencytrack.model.Project; +import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.ProjectRole.LdapUserProjectRole; +import org.dependencytrack.model.ProjectRole.ManagedUserProjectRole; +import org.dependencytrack.model.ProjectRole.OidcUserProjectRole; +import org.dependencytrack.model.Role; + +import org.jdbi.v3.core.mapper.RowMapper; +import org.jdbi.v3.core.statement.StatementContext; +import java.sql.ResultSet; +import java.sql.SQLException; + +import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.hasColumn; +import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.maybeSet; + +public class ProjectRoleRowMapper implements RowMapper { + + public ProjectRole map(final ResultSet resultSet, final StatementContext ctx) throws SQLException { + ProjectRole projectRole; + + switch (resultSet) { + case ResultSet rs when hasColumn(rs, "LDAPUSER_ID") -> projectRole = new LdapUserProjectRole(); + case ResultSet rs when hasColumn(rs, "MANAGEDUSER_ID") -> projectRole = new ManagedUserProjectRole(); + case ResultSet rs when hasColumn(rs, "OIDCUSER_ID") -> projectRole = new OidcUserProjectRole(); + default -> { + return null; + } + } + + maybeSet(resultSet, "PROJECT_ID", ResultSet::getLong, value -> { + var project = new Project(); + project.setId(value); + projectRole.setProject(project); + }); + + maybeSet(resultSet, "ROLE_ID", ResultSet::getLong, value -> { + var role = new Role(); + role.setId(value); + projectRole.setRole(role); + }); + + return projectRole; + } + +} diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index 3cac61d67e..23edd28f98 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -53,6 +53,13 @@ import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import org.dependencytrack.persistence.jdbi.RoleDao; +import org.jdbi.v3.core.Handle; + +import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; + +import java.util.ArrayList; +import java.util.List; import java.util.NoSuchElementException; /** @@ -107,6 +114,46 @@ public Response retrieveProjects(@Parameter(description = "The UUID of the team } } + @GET + @Path("/user/{username}") + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Returns the projects accessible by the specified user", + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

") + @PaginatedApi + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "Projects accessible by the specified user", + headers = @Header(name = TOTAL_COUNT_HEADER, description = "The total number of projects", + schema = @Schema(format = "integer")), + content = @Content(array = @ArraySchema(schema = @Schema(implementation = Project.class)))), + @ApiResponse(responseCode = "204", description = "No unassigned projects for specified user."), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "User not found"), + }) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ }) + public Response retrieveUserProjects( + @Parameter(description = "The username to retrieve projects for", required = true) @PathParam("username") String username) { + + try (QueryManager qm = new QueryManager()) { + User user = qm.getUser(username); + + if (user == null) + return Response.status(Response.Status.NOT_FOUND).build(); + + try (final Handle jdbiHandle = openJdbiHandle()) { + var dao = jdbiHandle.attach(RoleDao.class); + List projects = dao.getUserUnassignedProjects(principal); + + if (projects == null || projects.isEmpty()) + return Response.status(Response.Status.NOT_FOUND).entity("No unassigned projects for specified user.").build(); + + return Response.ok(projects).header(TOTAL_COUNT_HEADER, projects.size()).build(); + } + } + } + @PUT @Path("/mapping") @Produces(MediaType.APPLICATION_JSON) diff --git a/apiserver/src/main/resources/META-INF/persistence.xml b/apiserver/src/main/resources/META-INF/persistence.xml index 6dd905e48b..3a8d34ac99 100644 --- a/apiserver/src/main/resources/META-INF/persistence.xml +++ b/apiserver/src/main/resources/META-INF/persistence.xml @@ -40,12 +40,11 @@ org.dependencytrack.model.Component org.dependencytrack.model.ComponentOccurrence org.dependencytrack.model.ComponentProperty - org.dependencytrack.model.IntegrityMetaComponent + org.dependencytrack.model.DependencyMetrics org.dependencytrack.model.Epss org.dependencytrack.model.FindingAttribution org.dependencytrack.model.License org.dependencytrack.model.LicenseGroup - org.dependencytrack.model.MappedRole org.dependencytrack.model.NotificationPublisher org.dependencytrack.model.NotificationRule org.dependencytrack.model.Policy @@ -54,6 +53,9 @@ org.dependencytrack.model.Project org.dependencytrack.model.ProjectMetadata org.dependencytrack.model.ProjectProperty + org.dependencytrack.model.ProjectRole$LdapUserProjectRole + org.dependencytrack.model.ProjectRole$ManagedUserProjectRole + org.dependencytrack.model.ProjectRole$OidcUserProjectRole org.dependencytrack.model.Repository org.dependencytrack.model.RepositoryMetaComponent org.dependencytrack.model.ServiceComponent diff --git a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 4fae8ce2f8..73f2f49c25 100644 --- a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -19,29 +19,23 @@ package org.dependencytrack.persistence; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import javax.jdo.PersistenceManager; import javax.jdo.Query; -import org.dependencytrack.model.MappedRole; import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; +import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.persistence.jdbi.JdbiFactory; import org.dependencytrack.persistence.jdbi.RoleDao; -import org.jdbi.v3.core.Handle; import alpine.common.logging.Logger; -import alpine.model.LdapUser; -import alpine.model.ManagedUser; -import alpine.model.OidcUser; import alpine.model.Permission; import alpine.model.UserPrincipal; import alpine.resources.AlpineRequest; -import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; - final class RoleQueryManager extends QueryManager implements IQueryManager { private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); @@ -80,18 +74,33 @@ public Role getRole(String uuid) { return query.executeUnique(); } + @Override + public List getUserRoles(UserPrincipal user) { + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserRoles(user)); + } + public List getUnassignedProjects(final String username) { return getUnassignedProjects(getUserPrincipal(username)); } - public List getUnassignedProjects(final UserPrincipal principal) { - // TODO: Implement getUnassignedProjects - return Collections.emptyList(); + public List getUnassignedProjects(final UserPrincipal user) { + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserUnassignedProjects(user)); } public List getUnassignedRolePermissions(final Role role) { - // TODO: Implement getUnassignedRolePermissions - return Collections.emptyList(); + List permissions = new ArrayList<>(); + + var permissionNames = role.getPermissions().stream() + .map(Permission::getName) + .toList(); + + Query query = pm.newQuery(Permission.class) + .filter("!:permissionNames.contains(name)") + .setNamedParameters(Map.of("permissionNames", permissionNames)); + + permissions.addAll(executeAndCloseList(query)); + + return permissions; } @Override @@ -108,71 +117,14 @@ public Role updateRole(Role transientRole) { @Override public boolean addRoleToUser(UserPrincipal user, Role role, Project project) { - Query query = pm.newQuery(MappedRole.class) - .filter("project.id == :projectId && role.id == :roleId") - .setNamedParameters(Map.of( - "roleId", role.getId(), - "projectId", project.getId())); - - try { - query.getFetchPlan().setGroup(MappedRole.FetchGroup.ALL.name()); - MappedRole result = query.executeUnique(); - - if (result == null) { - LOGGER.info("Creating role mapping for project: %s / role: %s" - .formatted(project.getName(), role.getName())); - - result = new MappedRole(); - result.setProject(project); - result.setRole(role); - } - - result.setLdapUsers(result.getLdapUsers() != null ? result.getLdapUsers() : new ArrayList<>()); - result.setManagedUsers(result.getManagedUsers() != null ? result.getManagedUsers() : new ArrayList<>()); - result.setOidcUsers(result.getOidcUsers() != null ? result.getOidcUsers() : new ArrayList<>()); - - final MappedRole mappedRole = result; - - boolean modified = switch (user) { - case LdapUser ldapUser when !mappedRole.getLdapUsers().contains(ldapUser) -> { - mappedRole.addLdapUsers(ldapUser); - yield true; - } - case ManagedUser managedUser when !mappedRole.getManagedUsers().contains(managedUser) -> { - mappedRole.addManagedUsers(managedUser); - yield true; - } - case OidcUser oidcUser when !mappedRole.getOidcUsers().contains(oidcUser) -> { - mappedRole.addOidcUsers(oidcUser); - yield true; - } - default -> false; - }; - - if (modified) - persist(mappedRole); - - return modified; - } finally { - query.closeAll(); - } + return JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addRoleToUser(user, project.getId(), role.getId())) == 1; } @Override public boolean removeRoleFromUser(UserPrincipal user, Role role, Project project) { - try (final Handle jdbiHandle = openJdbiHandle()) { - int count = switch (user) { - case LdapUser ldapUser -> jdbiHandle.attach(RoleDao.class) - .removeRoleFromLdapUser(ldapUser.getId(), project.getId(), role.getId()); - case ManagedUser managedUser -> jdbiHandle.attach(RoleDao.class) - .removeRoleFromManagedUser(managedUser.getId(), project.getId(), role.getId()); - case OidcUser oidcUser -> jdbiHandle.attach(RoleDao.class) - .removeRoleFromOidcUser(oidcUser.getId(), project.getId(), role.getId()); - default -> 0; - }; - - return count == 1; - } + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser(user, + project, role.getId())) > 0; } diff --git a/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java new file mode 100644 index 0000000000..3a7bd058ef --- /dev/null +++ b/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -0,0 +1,112 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence.jdbi; + +import java.util.List; + +import org.dependencytrack.model.Project; +import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.persistence.jdbi.mapping.ProjectRoleRowMapper; + +import org.jdbi.v3.sqlobject.config.RegisterFieldMapper; +import org.jdbi.v3.sqlobject.config.RegisterRowMapper; +import org.jdbi.v3.sqlobject.customizer.Bind; +import org.jdbi.v3.sqlobject.customizer.Define; +import org.jdbi.v3.sqlobject.customizer.DefineNamedBindings; +import org.jdbi.v3.sqlobject.statement.SqlQuery; +import org.jdbi.v3.sqlobject.statement.SqlUpdate; + +import alpine.model.UserPrincipal; + +/** + * @since 5.6.0 + */ +public interface RoleDao { + + @SqlUpdate(/* language=sql */ """ + DELETE + FROM "ROLE" + WHERE "ID" = :roleId + """) + int deleteRole(@Bind final long roleId); + + @SqlUpdate(/* language=sql */ """ + <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> + <#assign prefix = user.getClass().getSimpleName()?upper_case> + INSERT INTO "${prefix}S_PROJECTS_ROLES" + ("${prefix}_ID", "PROJECT_ID", "ROLE_ID") + VALUES + (${user.getId()}, :projectId, :roleId) + ON CONFLICT DO NOTHING + """) + @DefineNamedBindings + int addRoleToUser(@Define T user, @Bind long projectId, @Bind long roleId); + + @SqlUpdate(/* language=sql */ """ + <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> + <#-- @ftlvariable name="project" type="org.dependencytrack.model.Project" --> + <#assign prefix = user.getClass().getSimpleName()?upper_case> + DELETE + FROM "${prefix}S_PROJECTS_ROLES" + WHERE "${prefix}_ID" = ${user.getId()} + AND "ROLE_ID" = :roleId + AND "PROJECT_ID" IN ( + SELECT "ID" + FROM "PROJECT" + WHERE "NAME" = '${project.getName()}' + ) + """) + @DefineNamedBindings + int removeRoleFromUser(@Define T user, @Define Project project, @Bind long roleId); + + @SqlQuery(/* language=sql */ """ + <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> + <#assign prefix = user.getClass().getSimpleName()?upper_case> + SELECT "PROJECT"."ID" AS "PROJECT_ID", + "ROLE"."ID" AS "ROLE_ID" + FROM "PROJECT" + INNER JOIN "${prefix}S_PROJECTS_ROLES" + ON "${prefix}S_PROJECTS_ROLES"."PROJECT_ID" = "PROJECT"."ID" + INNER JOIN "${prefix}" + ON "${prefix}"."ID" = "${prefix}S_PROJECTS_ROLES"."${prefix}_ID" + INNER JOIN "ROLE" + ON "ROLE"."ID" = "${prefix}S_PROJECTS_ROLES"."ROLE_ID" + WHERE "${prefix}"."USERNAME" != '${user.getUsername()}' + OR "${prefix}"."USERNAME" IS NULL + """) + @RegisterRowMapper(ProjectRoleRowMapper.class) + @DefineNamedBindings + List getUserRoles(@Define T user); + + @SqlQuery(/* language=sql */ """ + <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> + <#assign prefix = user.getClass().getSimpleName()?upper_case> + SELECT "PROJECT"."ID", "PROJECT"."NAME" + FROM "PROJECT" + LEFT JOIN "${prefix}S_PROJECTS_ROLES" + ON "${prefix}S_PROJECTS_ROLES"."PROJECT_ID" = "PROJECT"."ID" + LEFT JOIN "${prefix}" + ON "${prefix}"."ID" = "${prefix}S_PROJECTS_ROLES"."${prefix}_ID" + WHERE "${prefix}"."USERNAME" != '${user.getUsername()}' + OR "${prefix}"."USERNAME" IS NULL + """) + @RegisterFieldMapper(Project.class) + List getUserUnassignedProjects(@Define T user); + +} diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml index 6398466d0a..5966a812cd 100644 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -646,21 +646,8 @@
- - - - - - - - - - - - - - + @@ -706,36 +693,12 @@ - - - - - - - - - - - - - - - - + + - - + + @@ -748,12 +711,21 @@ validateUnique="true" validateForeignKey="true" /> - + + + + + @@ -762,8 +734,12 @@ + + + + - + @@ -776,12 +752,21 @@ validateUnique="true" validateForeignKey="true" /> - + + + + + @@ -790,8 +775,12 @@ + + + + - + @@ -804,14 +793,35 @@ validateUnique="true" validateForeignKey="true" /> - + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/migration/procedures/function_has-project-access.sql b/src/main/resources/migration/procedures/function_has-project-access.sql new file mode 100644 index 0000000000..3fd727255b --- /dev/null +++ b/src/main/resources/migration/procedures/function_has-project-access.sql @@ -0,0 +1,54 @@ +create or replace function has_project_access( + project_id bigint, + team_ids bigint[], + role_ids bigint[] +) returns bool + language "sql" + parallel safe + stable +as +$$ +with recursive project_hierarchy(id, parent_id) as( + select "ID" as id, + "PARENT_PROJECT_ID" as parent_id + from "PROJECT" + where "ID" = project_id + union all + select "PROJECT"."ID" as id, + "PROJECT"."PARENT_PROJECT_ID" as parent_id + from "PROJECT" + inner join project_hierarchy + on project_hierarchy.parent_id = "PROJECT"."ID" +) +select coalesce( + ( + select true + from project_hierarchy + inner join "PROJECT_ACCESS_TEAMS" + on "PROJECT_ACCESS_TEAMS"."PROJECT_ID" = project_hierarchy.id + where "PROJECT_ACCESS_TEAMS"."TEAM_ID" = any(team_ids) + ), + ( + select true + from project_hierarchy + inner join "LDAPUSERS_PROJECTS_ROLES" + on "LDAPUSERS_PROJECTS_ROLES"."PROJECT_ID" = project_hierarchy.id + where "LDAPUSERS_PROJECTS_ROLES"."ROLE_ID" = any(role_ids) + ), + ( + select true + from project_hierarchy + inner join "MANAGEDUSERS_PROJECTS_ROLES" + on "MANAGEDUSERS_PROJECTS_ROLES"."PROJECT_ID" = project_hierarchy.id + where "MANAGEDUSERS_PROJECTS_ROLES"."ROLE_ID" = any(role_ids) + ), + ( + select true + from project_hierarchy + inner join "OIDCUSERS_PROJECTS_ROLES" + on "OIDCUSERS_PROJECTS_ROLES"."PROJECT_ID" = project_hierarchy.id + where "OIDCUSERS_PROJECTS_ROLES"."ROLE_ID" = any(role_ids) + ), + false +) +$$; \ No newline at end of file From 17a521085bf3264219188ac4e7ed32edd5af549e Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Wed, 19 Mar 2025 16:31:28 -0500 Subject: [PATCH 14/45] refactor: create view of project effective permissions for user (#15) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../persistence/QueryManager.java | 18 ++-- .../persistence/RoleQueryManager.java | 91 ++++++++++++++++--- .../resources/migration/changelog-v5.6.0.xml | 25 +++++ 3 files changed, 116 insertions(+), 18 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 915bd9d8e1..05ef2a4cb7 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -526,11 +526,13 @@ protected Set getRoleIds(final Principal principal, final Project project) * @return A {@link Set} of {@link Team} IDs */ protected Set getTeamIds(final Principal principal) { - return switch (principal) { - case UserPrincipal userPrincipal -> Set.of(userPrincipal.getTeams().toArray(Long[]::new)); - case ApiKey apiKey -> Set.of(apiKey.getTeams().toArray(Long[]::new)); - default -> Collections.emptySet(); + List teams = switch (principal) { + case UserPrincipal user -> user.getTeams(); + case ApiKey apiKey -> apiKey.getTeams(); + default -> Collections.emptyList(); }; + + return Set.copyOf(teams.stream().map(Team::getId).toList()); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1154,11 +1156,15 @@ public List getUnassignedRolePermissions(final Role role) { return getRoleQueryManager().getUnassignedRolePermissions(role); } - public List getUserRoles(UserPrincipal user) { + public List getUserRoles(final UserPrincipal user) { return getRoleQueryManager().getUserRoles(user); } - public boolean removeRoleFromUser(UserPrincipal user, Role role, Project project) { + public List getUserProjectPermissions(final String username, final String projectName) { + return getRoleQueryManager().getUserProjectPermissions(username, projectName); + } + + public boolean removeRoleFromUser(final UserPrincipal user, final Role role, final Project project) { return getRoleQueryManager().removeRoleFromUser(user, role, project); } diff --git a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 73f2f49c25..3219ca7f28 100644 --- a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import javax.jdo.PersistenceManager; import javax.jdo.Query; @@ -32,12 +33,29 @@ import org.dependencytrack.persistence.jdbi.RoleDao; import alpine.common.logging.Logger; +import alpine.model.LdapUser; +import alpine.model.ManagedUser; +import alpine.model.OidcUser; import alpine.model.Permission; import alpine.model.UserPrincipal; import alpine.resources.AlpineRequest; final class RoleQueryManager extends QueryManager implements IQueryManager { + /** + * Represents a row returned by the USER_PROJECT_EFFECTIVE_PERMISSIONS view. + * + * @since 5.6.0 + */ + public record UserProjectEffectivePermissionsRow( + Long ldapUserId, + Long managedUserId, + Long oidcUserId, + Long projectId, + Long permissionId, + String permissionName) { + } + private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); RoleQueryManager(final PersistenceManager pm) { @@ -49,8 +67,8 @@ final class RoleQueryManager extends QueryManager implements IQueryManager { } @Override - public Role createRole(final String name, final String description, final List permissions) { - Role role = new Role(); + public Role createRole(final String name, final List permissions) { + final Role role = new Role(); role.setName(name); role.setDescription(description); role.setPermissions(permissions); @@ -68,15 +86,15 @@ public List getRoles() { } @Override - public Role getRole(String uuid) { + public Role getRole(final String uuid) { final Query query = pm.newQuery(Role.class, "uuid == :uuid"); return query.executeUnique(); } @Override - public List getUserRoles(UserPrincipal user) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserRoles(user)); + public List getUserRoles(final UserPrincipal user) { + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserRoles(user.getUsername())); } public List getUnassignedProjects(final String username) { @@ -88,13 +106,13 @@ public List getUnassignedProjects(final UserPrincipal user) { } public List getUnassignedRolePermissions(final Role role) { - List permissions = new ArrayList<>(); + final List permissions = new ArrayList<>(); - var permissionNames = role.getPermissions().stream() + final var permissionNames = role.getPermissions().stream() .map(Permission::getName) .toList(); - Query query = pm.newQuery(Permission.class) + final Query query = pm.newQuery(Permission.class) .filter("!:permissionNames.contains(name)") .setNamedParameters(Map.of("permissionNames", permissionNames)); @@ -104,7 +122,7 @@ public List getUnassignedRolePermissions(final Role role) { } @Override - public Role updateRole(Role transientRole) { + public Role updateRole(final Role transientRole) { final Role role = getObjectByUuid(Role.class, transientRole.getUuid()); if (role == null) return null; @@ -116,16 +134,65 @@ public Role updateRole(Role transientRole) { } @Override - public boolean addRoleToUser(UserPrincipal user, Role role, Project project) { + public List getUserProjectPermissions(final String username, final String projectName) { + final UserPrincipal user = getUserPrincipal(username); + final String columnName; + + switch (user) { + case LdapUser ldapUser -> columnName = "LDAPUSER_ID"; + case ManagedUser managedUser -> columnName = "MANAGEDUSER_ID"; + case OidcUser oidcUser -> columnName = "OIDCUSER_ID"; + default -> { + return null; + } + }; + + final Query projectsQuery = pm.newQuery(Project.class) + .filter("name == :projectName") + .setNamedParameters(Map.of("projectName", projectName)); + + final String projectIds = executeAndCloseList(projectsQuery).stream() + .map(Project::getId) + .map(String::valueOf) + .collect(Collectors.joining(", ", "'{", "}'")); + + // language=SQL + final var queryString = """ + SELECT + upep."LDAPUSER_ID", + upep."MANAGEDUSER_ID", + upep."OIDCUSER_ID", + upep."PROJECT_ID", + upep."PERMISSION_ID", + upep."PERMISSION_NAME" + FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" upep + WHERE upep."%s" = :userId + AND upep."PROJECT_ID" = ANY(%s) + """.formatted(columnName, projectIds); + + final Query query = pm.newQuery(Query.SQL, queryString); + query.setNamedParameters(Map.of( + "userId", user.getId(), + "projectIds", projectIds)); + + return executeAndCloseResultList(query, UserProjectEffectivePermissionsRow.class) + .stream() + .map(UserProjectEffectivePermissionsRow::permissionName) + .map(this::getPermission) + .distinct() + .toList(); + } + + @Override + public boolean addRoleToUser(final UserPrincipal user, final Role role, final Project project) { return JdbiFactory.withJdbiHandle( handle -> handle.attach(RoleDao.class).addRoleToUser(user, project.getId(), role.getId())) == 1; } @Override - public boolean removeRoleFromUser(UserPrincipal user, Role role, Project project) { + public boolean removeRoleFromUser(final UserPrincipal user, final Role role, final Project project) { return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser(user, project, role.getId())) > 0; - } } diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml index 5966a812cd..286ccd73b8 100644 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -823,5 +823,30 @@ + + + SELECT + lpr."LDAPUSER_ID" AS "LDAPUSER_ID", + mpr."MANAGEDUSER_ID" AS "MANAGEDUSER_ID", + opr."OIDCUSER_ID" AS "OIDCUSER_ID", + pr."ID" AS "PROJECT_ID", + p."ID" AS "PERMISSION_ID", + p."NAME" AS "PERMISSION_NAME" + FROM "PERMISSION" p + INNER JOIN "ROLES_PERMISSIONS" rp + ON rp."PERMISSION_ID" = p."ID" + FULL OUTER JOIN "LDAPUSERS_PROJECTS_ROLES" lpr + ON lpr."ROLE_ID" = rp."ROLE_ID" + FULL OUTER JOIN "MANAGEDUSERS_PROJECTS_ROLES" mpr + ON lpr."PROJECT_ID" = mpr."PROJECT_ID" + AND lpr."ROLE_ID" = mpr."ROLE_ID" + FULL OUTER JOIN "OIDCUSERS_PROJECTS_ROLES" opr + ON mpr."PROJECT_ID" = opr."PROJECT_ID" + AND mpr."ROLE_ID" = opr."ROLE_ID" + INNER JOIN "PROJECT" pr + ON lpr."PROJECT_ID" = pr."ID" + OR mpr."PROJECT_ID" = pr."ID" + OR opr."PROJECT_ID" = pr."ID" + From 894d7991196e66cdcb42f312849b897f62ea96a6 Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Mon, 24 Mar 2025 15:12:44 -0500 Subject: [PATCH 15/45] Role DAO fixes (#16) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../dependencytrack/model/ProjectRole.java | 15 +- .../java/org/dependencytrack/model/Role.java | 40 +-- .../persistence/QueryManager.java | 2 +- .../jdbi/mapping/ProjectRoleRowMapper.java | 2 +- .../resources/v1/AccessControlResource.java | 2 +- .../resources/v1/RoleResource.java | 2 +- .../persistence/DefaultObjectGenerator.java | 264 ++++++++---------- .../persistence/RoleQueryManager.java | 38 ++- .../persistence/jdbi/RoleDao.java | 76 +++-- .../resources/migration/changelog-v5.6.0.xml | 70 ++++- 10 files changed, 267 insertions(+), 244 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java index dbf4807603..32be80ee8a 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java @@ -85,10 +85,7 @@ public void setProject(Project project) { * @since 5.6.0 */ @PersistenceCapable(table = "LDAPUSERS_PROJECTS_ROLES") - @Unique(name = "LDAPUSERS_PROJECTS_ROLES_COMPOSITE_IDX", - table = "LDAPUSERS_PROJECTS_ROLES", - members = { "ldapUsers", "project", "role" }, - deferred = "true") + @Unique(name = "LDAPUSERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "ldapUsers", "project", "role" }) @FetchGroup(name = "ALL", members = { @Persistent(name = "role"), @Persistent(name = "project"), @@ -136,10 +133,7 @@ public void addLdapUsers(LdapUser... ldapUsers) { * @since 5.6.0 */ @PersistenceCapable(table = "MANAGEDUSERS_PROJECTS_ROLES") - @Unique(name = "MANAGEDUSERS_PROJECTS_ROLES_COMPOSITE_IDX", - table = "MANAGEDUSERS_PROJECTS_ROLES", - members = { "managedUsers", "project", "role" }, - deferred = "true") + @Unique(name = "MANAGEDUSERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "managedUsers", "project", "role" }) @FetchGroup(name = "ALL", members = { @Persistent(name = "role"), @Persistent(name = "project"), @@ -187,10 +181,7 @@ public void addManagedUsers(ManagedUser... managedUsers) { * @since 5.6.0 */ @PersistenceCapable(table = "OIDCUSERS_PROJECTS_ROLES") - @Unique(name = "OIDCUSERS_PROJECTS_ROLES_COMPOSITE_IDX", - table = "OIDCUSERS_PROJECTS_ROLES", - members = { "oidcUsers", "project", "role" }, - deferred = "true") + @Unique(name = "OIDCUSERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "oidcUsers", "project", "role" }) @FetchGroup(name = "ALL", members = { @Persistent(name = "role"), @Persistent(name = "project"), diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 47f8516575..8f4ca117b3 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -32,9 +32,10 @@ import jakarta.validation.constraints.Size; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; + +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; import java.util.UUID; import javax.jdo.annotations.Column; @@ -86,8 +87,7 @@ public enum FetchGroup { @NotBlank @Size(min = 1, max = 255) @JsonDeserialize(using = TrimmedStringDeserializer.class) - @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, - message = "The name may only contain printable characters") + @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The name may only contain printable characters") private String name; @Persistent @@ -103,7 +103,7 @@ public enum FetchGroup { @Join(column = "ROLE_ID") @Element(column = "PERMISSION_ID") @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "name ASC")) - private List permissions; + private Set permissions = new LinkedHashSet<>(); @Persistent(customValueStrategy = "uuid") @Unique(name = "ROLE_UUID_IDX") @@ -127,32 +127,18 @@ public void setName(String name) { this.name = name; } - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public List getPermissions() { + public Set getPermissions() { return permissions; } - public void setPermissions(List permissions) { + public void setPermissions(Set permissions) { this.permissions = permissions; } - public void addPermissions(Permission... permissions) { - if (this.permissions == null) { - this.permissions = new ArrayList<>(Arrays.asList(permissions)); + public boolean addPermissions(Permission... permissions) { + this.permissions = Objects.requireNonNullElse(this.permissions, new LinkedHashSet<>()); - return; - } - - for (var permission : permissions) - if (!this.permissions.contains(permission)) - this.permissions.add(permission); + return this.permissions.addAll(Set.of(permissions)); } public UUID getUuid() { @@ -169,11 +155,13 @@ public String toString() { .map(permission -> permission.getName()) .toList(); - return "%s{id=%d, name='%s', description='%s', permissions=%s}".formatted( + return "%s{id=%d, uuid='%s', name='%s', permissions=%s}".formatted( getClass().getSimpleName(), id, + uuid, name, description != null ? description : "", permissionStrings); } + } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 05ef2a4cb7..d395b5c20c 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -890,7 +890,7 @@ public List getRoles() { } public Role getRole(String uuid) { - return getRoleQueryManager().getRole(null); + return getRoleQueryManager().getRole(uuid); } public Role updateRole(Role transientRole) { diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java index d71d0bfdbe..e34bab48ff 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java @@ -36,7 +36,7 @@ public class ProjectRoleRowMapper implements RowMapper { public ProjectRole map(final ResultSet resultSet, final StatementContext ctx) throws SQLException { - ProjectRole projectRole; + final ProjectRole projectRole; switch (resultSet) { case ResultSet rs when hasColumn(rs, "LDAPUSER_ID") -> projectRole = new LdapUserProjectRole(); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index 23edd28f98..b319dd9ef8 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -144,7 +144,7 @@ public Response retrieveUserProjects( try (final Handle jdbiHandle = openJdbiHandle()) { var dao = jdbiHandle.attach(RoleDao.class); - List projects = dao.getUserUnassignedProjects(principal); + List projects = dao.getUserUnassignedProjects(principal.getClass(), principal.getUsername()); if (projects == null || projects.isEmpty()) return Response.status(Response.Status.NOT_FOUND).entity("No unassigned projects for specified user.").build(); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index 029c38ef68..c406cd3f6f 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -142,7 +142,7 @@ public Response createRole(Role jsonRole) { failOnValidationError(super.getValidator().validateProperty(jsonRole, "name")); try (QueryManager qm = new QueryManager()) { - final Role role = qm.createRole(jsonRole.getName(), jsonRole.getDescription(), jsonRole.getPermissions()); + final Role role = qm.createRole(jsonRole.getName(), jsonRole.getPermissions().stream().toList()); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Role created: " + role.getName()); return Response.status(Response.Status.CREATED).entity(role).build(); diff --git a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java index fa2b4c030c..d8845a8b75 100644 --- a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java +++ b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java @@ -40,7 +40,8 @@ import java.io.IOException; import java.time.Duration; import java.time.Instant; -import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import static net.javacrumbs.shedlock.core.LockAssert.assertLocked; @@ -56,6 +57,56 @@ public class DefaultObjectGenerator implements ServletContextListener { private static final Logger LOGGER = Logger.getLogger(DefaultObjectGenerator.class); + private static final Map PERMISSIONS_MAP = new HashMap<>(); + + private static final Map> DEFAULT_TEAM_PERMISSIONS = Map.of( + "Administrators", Stream.of(Permissions.values()) + .map(Permissions::name) + .toList(), + "Portfolio Managers", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.PORTFOLIO_MANAGEMENT, + Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, + Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE), + "Automation", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.BOM_UPLOAD), + "Badge Viewers", List.of( + Permissions.Constants.VIEW_BADGES)); + + private static final Map> DEFAULT_ROLE_PERMISSIONS = Map.of( + "Project Admin", List.of( + Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, + Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE, + Permissions.Constants.VULNERABILITY_ANALYSIS, + Permissions.Constants.VULNERABILITY_ANALYSIS_CREATE, + Permissions.Constants.VULNERABILITY_ANALYSIS_READ, + Permissions.Constants.VULNERABILITY_ANALYSIS_UPDATE, + Permissions.Constants.POLICY_MANAGEMENT, + Permissions.Constants.POLICY_MANAGEMENT_CREATE, + Permissions.Constants.POLICY_MANAGEMENT_READ, + Permissions.Constants.POLICY_MANAGEMENT_UPDATE, + Permissions.Constants.POLICY_MANAGEMENT_DELETE), + "Project Auditor", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.VIEW_VULNERABILITY, + Permissions.Constants.VIEW_POLICY_VIOLATION, + Permissions.Constants.VULNERABILITY_ANALYSIS_READ), + "Project Editor", List.of( + Permissions.Constants.BOM_UPLOAD, + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, + Permissions.Constants.VIEW_VULNERABILITY, + Permissions.Constants.VULNERABILITY_ANALYSIS_READ, + Permissions.Constants.PROJECT_CREATION_UPLOAD), + "Project Viewer", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.VIEW_VULNERABILITY, + Permissions.Constants.VIEW_BADGES)); /** * {@inheritDoc} @@ -113,15 +164,17 @@ private void executeLocked() { // TODO: Make population transactional with recordDefaultObjectsVersion(). LOGGER.info("Initializing default object generator"); - loadDefaultPermissions(); - loadDefaultPersonas(); - loadDefaultLicenses(); - loadDefaultLicenseGroups(); - loadDefaultRepositories(); - loadDefaultConfigProperties(); - loadDefaultNotificationPublishers(); - - recordDefaultObjectsVersion(); + try (final var qm = new QueryManager()) { + loadDefaultPermissions(qm); + loadDefaultPersonas(qm); + loadDefaultLicenses(qm); + loadDefaultLicenseGroups(qm); + loadDefaultRepositories(qm); + loadDefaultRoles(qm); + loadDefaultConfigProperties(qm); + loadDefaultNotificationPublishers(qm); + recordDefaultObjectsVersion(qm); + } } /** @@ -201,15 +254,25 @@ private void loadDefaultLicenseGroups() { /** * Loads the default permissions */ - public void loadDefaultPermissions() { - try (QueryManager qm = new QueryManager()) { - LOGGER.info("Synchronizing permissions to datastore"); - for (final Permissions permission : Permissions.values()) { - if (qm.getPermission(permission.name()) == null) { - LOGGER.debug("Creating permission: " + permission.name()); - qm.createPermission(permission.name(), permission.getDescription()); - } + private void loadDefaultPermissions(final QueryManager qm) { + LOGGER.info("Synchronizing permissions to datastore"); + + List existing = Objects.requireNonNullElse(qm.getPermissions(), Collections.emptyList()) + .stream() + .map(Permission::getName) + .toList(); + + for (final Permissions value : Permissions.values()) + if (!existing.contains(value.name())) { + LOGGER.debug("Creating permission: " + value.name()); + PERMISSIONS_MAP.put(value.name(), qm.createPermission(value.name(), value.getDescription())); } + } + + @SuppressWarnings("unused") + private void loadDefaultPersonas() { + try (final var qm = new QueryManager()) { + loadDefaultPersonas(qm); } } @@ -226,16 +289,21 @@ private void loadDefaultPersonas() { ManagedUser admin = qm.createManagedUser("admin", "Administrator", "admin@localhost", new String(PasswordService.createHash("admin".toCharArray())), true, true, false); - LOGGER.debug("Creating team: Administrators"); - final Team sysadmins = qm.createTeam("Administrators", false); - LOGGER.debug("Creating team: Portfolio Managers"); - final Team managers = qm.createTeam("Portfolio Managers", false); - LOGGER.debug("Creating team: Automation"); - final Team automation = qm.createTeam("Automation", true); - LOGGER.debug("Creating team: Badge Viewers"); - final Team badges = qm.createTeam("Badge Viewers", true); + LOGGER.info("Adding default users and teams to datastore"); + + LOGGER.debug("Creating user: admin"); + ManagedUser admin = qm.createManagedUser("admin", "Administrator", "admin@localhost", + new String(PasswordService.createHash("admin".toCharArray())), true, true, false); - final List fullList = qm.getPermissions(); + for (var name : new String[] { "Administrators", "Portfolio Managers", "Automation", "Badge Viewers" }) { + LOGGER.debug("Creating team: " + name); + var team = qm.createTeam(name); + + LOGGER.debug("Assigning default permissions for team: " + name); + team.setPermissions(getPermissionsByName(DEFAULT_TEAM_PERMISSIONS.get(name))); + + qm.persist(team); + } LOGGER.debug("Assigning default permissions to teams"); sysadmins.setPermissions(fullList); @@ -257,142 +325,28 @@ private void loadDefaultPersonas() { } } - private List getPortfolioManagersPermissions(final List fullList) { - final List permissions = new ArrayList<>(); - for (final Permission permission: fullList) { - if (permission.getName().equals(Permissions.Constants.VIEW_PORTFOLIO) || - permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT) || - permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE) || - permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_READ) || - permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE) || - permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE)) { - permissions.add(permission); - } - } - return permissions; - } - - private List getAutomationPermissions(final List fullList) { - final List permissions = new ArrayList<>(); - for (final Permission permission: fullList) { - if (permission.getName().equals(Permissions.Constants.VIEW_PORTFOLIO) || - permission.getName().equals(Permissions.Constants.BOM_UPLOAD)) { - permissions.add(permission); - } - } - return permissions; + /** + * Loads the default repositories + */ + private List getPermissionsByName(List names) { + return names.stream().map(PERMISSIONS_MAP::get).filter(Objects::nonNull).toList(); } - private List getBadgesPermissions(final List fullList) { - final List permissions = new ArrayList<>(); - for (final Permission permission : fullList) { - if (permission.getName().equals(Permissions.Constants.VIEW_BADGES)) { - permissions.add(permission); - } - } - return permissions; - } - /** * Loads the default Roles */ - private void loadDefaultRoles() { - try (QueryManager qm = new QueryManager()) { - if (!qm.getRoles().isEmpty()) { - return; - } - LOGGER.info("Adding default roles to datastore"); - LOGGER.debug("Creating role: Project Admin"); - final Role projectAdmin = qm.createRole("Project Admin", false); - LOGGER.debug("Creating role: Project Auditor"); - final Role projectAuditor = qm.createRole("Project Auditor", false); - LOGGER.debug("Creating role: Project Editor"); - final Role projectEditor = qm.createRole("Project Editor", false); - LOGGER.debug("Creating role: Project Viewer"); - final Role projectViewer = qm.createRole("Project Viewer", true); - - final List fullList = qm.getPermissions(); - - LOGGER.debug("Assigning default permissions to roles"); - projectAdmin.setPermissions(getProjectAdminPermissions(fullList)); - projectAuditor.setPermissions(getProjectAuditorPermissions(fullList)); - projectEditor.setPermissions(getProjectEditorPermissions(fullList)); - projectViewer.setPermissions(getProjectViewerPermissions(fullList)); - - qm.persist(projectAdmin); - qm.persist(projectAuditor); - qm.persist(projectEditor); - qm.persist(projectViewer); - } - } - - private List getProjectAdminPermissions(final List fullList) { - final List permissions = new ArrayList<>(); - for (final Permission permission : fullList) { - if (permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT.name()) || - permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_CREATE.name()) || - permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_READ.name()) || - permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_UPDATE.name()) || - permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_DELETE.name()) || - permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS.name()) || - permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_CREATE.name()) || - permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_READ.name()) || - permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_UPDATE.name()) || - permission.getName().equals(Permissions.POLICY_MANAGEMENT.name()) || - permission.getName().equals(Permissions.POLICY_MANAGEMENT_CREATE.name()) || - permission.getName().equals(Permissions.POLICY_MANAGEMENT_READ.name()) || - permission.getName().equals(Permissions.POLICY_MANAGEMENT_UPDATE.name()) || - permission.getName().equals(Permissions.POLICY_MANAGEMENT_DELETE.name())) { - permissions.add(permission); - } - } - return permissions; - } - - private List getProjectAuditorPermissions(final List fullList) { - final List permissions = new ArrayList<>(); - for (final Permission permission : fullList) { - if (permission.getName().equals(Permissions.VIEW_PORTFOLIO.name()) || - permission.getName().equals(Permissions.VIEW_VULNERABILITY.name()) || - permission.getName().equals(Permissions.VIEW_POLICY_VIOLATION.name()) || - permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_READ.name())) { - permissions.add(permission); - } - } - return permissions; - } - - private List getProjectEditorPermissions(final List fullList) { - final List permissions = new ArrayList<>(); - for (final Permission permission : fullList) { - if (permission.getName().equals(Permissions.BOM_UPLOAD.name()) || - permission.getName().equals(Permissions.VIEW_PORTFOLIO.name()) || - permission.getName().equals(Permissions.PORTFOLIO_MANAGEMENT_READ.name()) || - permission.getName().equals(Permissions.VIEW_VULNERABILITY.name()) || - permission.getName().equals(Permissions.VULNERABILITY_ANALYSIS_READ.name()) || - permission.getName().equals(Permissions.PROJECT_CREATION_UPLOAD.name())) { - permissions.add(permission); - } - } - return permissions; - } - - private List getProjectViewerPermissions(final List fullList) { - final List permissions = new ArrayList<>(); - for (final Permission permission : fullList) { - if (permission.getName().equals(Permissions.VIEW_PORTFOLIO.name()) || - permission.getName().equals(Permissions.VIEW_VULNERABILITY.name()) || - permission.getName().equals(Permissions.VIEW_BADGES.name())) { - permissions.add(permission); - } + private void loadDefaultRoles(final QueryManager qm) { + if (!qm.getRoles().isEmpty()) + return; + + LOGGER.info("Adding default roles to datastore"); + + for (var name : new String[] { "Project Admin", "Project Auditor", "Project Editor", "Project Viewer" }) { + LOGGER.debug("Creating role: " + name); + qm.createRole(name, getPermissionsByName(DEFAULT_ROLE_PERMISSIONS.get(name))); } - return permissions; } - - /** - * Loads the default repositories - */ public void loadDefaultRepositories() { try (QueryManager qm = new QueryManager()) { LOGGER.info("Synchronizing default repositories to datastore"); diff --git a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 3219ca7f28..437a25e2d0 100644 --- a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import javax.jdo.PersistenceManager; @@ -68,12 +69,13 @@ public record UserProjectEffectivePermissionsRow( @Override public Role createRole(final String name, final List permissions) { - final Role role = new Role(); - role.setName(name); - role.setDescription(description); - role.setPermissions(permissions); + return callInTransaction(() -> { + final Role role = new Role(); + role.setName(name); + role.setPermissions(Set.copyOf(permissions)); - return persist(role); + return persist(role); + }); } @Override @@ -87,14 +89,13 @@ public List getRoles() { @Override public Role getRole(final String uuid) { - final Query query = pm.newQuery(Role.class, "uuid == :uuid"); - - return query.executeUnique(); + return getObjectByUuid(Role.class, uuid, Role.FetchGroup.ALL.name()); } @Override public List getUserRoles(final UserPrincipal user) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserRoles(user.getUsername())); + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class) + .getUserRoles(user.getClass(), user.getUsername())); } public List getUnassignedProjects(final String username) { @@ -102,7 +103,9 @@ public List getUnassignedProjects(final String username) { } public List getUnassignedProjects(final UserPrincipal user) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserUnassignedProjects(user)); + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserUnassignedProjects( + user.getClass(), + user.getUsername())); } public List getUnassignedRolePermissions(final Role role) { @@ -145,7 +148,7 @@ public List getUserProjectPermissions(final String username, final S default -> { return null; } - }; + } final Query projectsQuery = pm.newQuery(Project.class) .filter("name == :projectName") @@ -186,13 +189,20 @@ public List getUserProjectPermissions(final String username, final S @Override public boolean addRoleToUser(final UserPrincipal user, final Role role, final Project project) { return JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser(user, project.getId(), role.getId())) == 1; + handle -> handle.attach(RoleDao.class).addRoleToUser( + user.getClass(), + user.getId(), + project.getId(), + role.getId())) == 1; } @Override public boolean removeRoleFromUser(final UserPrincipal user, final Role role, final Project project) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser(user, - project, role.getId())) > 0; + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser( + user.getClass(), + user.getId(), + project.getName(), + role.getId())) > 0; } } diff --git a/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java index 3a7bd058ef..7990b5ebea 100644 --- a/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ b/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -48,65 +48,79 @@ public interface RoleDao { @SqlUpdate(/* language=sql */ """ <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = user.getClass().getSimpleName()?upper_case> + <#assign prefix = userClass.getSimpleName()?upper_case> INSERT INTO "${prefix}S_PROJECTS_ROLES" ("${prefix}_ID", "PROJECT_ID", "ROLE_ID") VALUES - (${user.getId()}, :projectId, :roleId) + (:userId, :projectId, :roleId) ON CONFLICT DO NOTHING """) @DefineNamedBindings - int addRoleToUser(@Define T user, @Bind long projectId, @Bind long roleId); + int addRoleToUser( + @Define Class userClass, + @Bind long userId, + @Bind long projectId, + @Bind long roleId); @SqlUpdate(/* language=sql */ """ <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#-- @ftlvariable name="project" type="org.dependencytrack.model.Project" --> - <#assign prefix = user.getClass().getSimpleName()?upper_case> + <#assign prefix = userClass.getSimpleName()?upper_case> DELETE FROM "${prefix}S_PROJECTS_ROLES" - WHERE "${prefix}_ID" = ${user.getId()} + WHERE "${prefix}_ID" = :userId AND "ROLE_ID" = :roleId AND "PROJECT_ID" IN ( SELECT "ID" FROM "PROJECT" - WHERE "NAME" = '${project.getName()}' + WHERE "NAME" = :projectName ) """) @DefineNamedBindings - int removeRoleFromUser(@Define T user, @Define Project project, @Bind long roleId); + int removeRoleFromUser( + @Define Class userClass, + @Bind long userId, + @Bind String projectName, + @Bind long roleId); @SqlQuery(/* language=sql */ """ <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = user.getClass().getSimpleName()?upper_case> - SELECT "PROJECT"."ID" AS "PROJECT_ID", - "ROLE"."ID" AS "ROLE_ID" - FROM "PROJECT" - INNER JOIN "${prefix}S_PROJECTS_ROLES" - ON "${prefix}S_PROJECTS_ROLES"."PROJECT_ID" = "PROJECT"."ID" - INNER JOIN "${prefix}" - ON "${prefix}"."ID" = "${prefix}S_PROJECTS_ROLES"."${prefix}_ID" - INNER JOIN "ROLE" - ON "ROLE"."ID" = "${prefix}S_PROJECTS_ROLES"."ROLE_ID" - WHERE "${prefix}"."USERNAME" != '${user.getUsername()}' - OR "${prefix}"."USERNAME" IS NULL + <#assign prefix = userClass.getSimpleName()?upper_case> + SELECT + p."ID" AS "PROJECT_ID", + p."NAME" AS "PROJECT_NAME", + p."UUID" AS "PROJECT_UUID", + r."ID" AS "ROLE_ID", + r."NAME" AS "ROLE_NAME", + r."UUID" AS "ROLE_UUID", + u."ID" AS "${prefix}_ID" + FROM "PROJECT" p + INNER JOIN "${prefix}S_PROJECTS_ROLES" pr + ON pr."PROJECT_ID" = p."ID" + INNER JOIN "${prefix}" u + ON u."ID" = pr."${prefix}_ID" + INNER JOIN "ROLE" r + ON r."ID" = pr."ROLE_ID" + WHERE u."USERNAME" = :username """) @RegisterRowMapper(ProjectRoleRowMapper.class) @DefineNamedBindings - List getUserRoles(@Define T user); + List getUserRoles(@Define Class userClass, @Bind String username); @SqlQuery(/* language=sql */ """ <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = user.getClass().getSimpleName()?upper_case> - SELECT "PROJECT"."ID", "PROJECT"."NAME" - FROM "PROJECT" - LEFT JOIN "${prefix}S_PROJECTS_ROLES" - ON "${prefix}S_PROJECTS_ROLES"."PROJECT_ID" = "PROJECT"."ID" - LEFT JOIN "${prefix}" - ON "${prefix}"."ID" = "${prefix}S_PROJECTS_ROLES"."${prefix}_ID" - WHERE "${prefix}"."USERNAME" != '${user.getUsername()}' - OR "${prefix}"."USERNAME" IS NULL + <#assign prefix = userClass.getSimpleName()?upper_case> + SELECT p."ID", p."NAME", p."UUID" + FROM "PROJECT" p + LEFT JOIN "${prefix}S_PROJECTS_ROLES" pr + ON pr."PROJECT_ID" = p."ID" + LEFT JOIN "${prefix}" u + ON u."ID" = pr."${prefix}_ID" + WHERE u."USERNAME" != :username + OR u."USERNAME" IS NULL """) @RegisterFieldMapper(Project.class) - List getUserUnassignedProjects(@Define T user); + List getUserUnassignedProjects( + @Define Class userClass, + @Bind String username); } diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml index 286ccd73b8..5d0ed6292d 100644 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ b/src/main/resources/migration/changelog-v5.6.0.xml @@ -637,7 +637,73 @@ referencedTableName="WORKFLOW_STATE" validate="true"/> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WITH + cte_duplicate AS ( + SELECT "PROJECT_ID" + , "TEAM_ID" + FROM "PROJECT_ACCESS_TEAMS" + GROUP BY "PROJECT_ID" + , "TEAM_ID" + HAVING COUNT(*) > 1 + ), + cte_deleted_duplicate AS ( + DELETE FROM "PROJECT_ACCESS_TEAMS" + USING cte_duplicate + WHERE cte_duplicate."PROJECT_ID" = "PROJECT_ACCESS_TEAMS"."PROJECT_ID" + AND cte_duplicate."TEAM_ID" = "PROJECT_ACCESS_TEAMS"."TEAM_ID" + ) + INSERT INTO "PROJECT_ACCESS_TEAMS" ("PROJECT_ID", "TEAM_ID") + SELECT "PROJECT_ID", "TEAM_ID" FROM cte_duplicate + + + + + @@ -650,7 +716,7 @@ - + From 02c3b03b9b9a29d7be7eb486a3d5d1f97d6bfdec Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Sat, 29 Mar 2025 16:35:27 -0600 Subject: [PATCH 16/45] Revert "feat: get user project permissions (wip) (#11)" (#17) This reverts commit 44dd2a22df446fcb7760c730b57483ad87e63fbd. Signed-off-by: Allen Shearin --- .../persistence/RoleQueryManagerTest.java | 171 ------------------ 1 file changed, 171 deletions(-) delete mode 100644 apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java deleted file mode 100644 index c59227b733..0000000000 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.persistence; - -import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRole; -import org.dependencytrack.model.ProjectRole.LdapUserProjectRole; -import org.dependencytrack.model.ProjectRole.ManagedUserProjectRole; -import org.dependencytrack.model.ProjectRole.OidcUserProjectRole; -import org.dependencytrack.model.Role; -import org.jdbi.v3.core.Jdbi; - -import alpine.Config; -import alpine.model.ManagedUser; -import alpine.model.Permission; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.dependencytrack.PersistenceCapableTest; -import org.dependencytrack.common.ConfigKey; -import org.dependencytrack.event.kafka.KafkaProducerInitializer; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.utility.DockerImageName; - -import com.github.tomakehurst.wiremock.junit.WireMockRule; - -public class RoleQueryManagerTest extends PersistenceCapableTest { - - private PostgreSQLContainer postgresContainer; - private Jdbi jdbi; - - @Before - public void setUp() { - System.setProperty("javax.jdo.PersistenceManagerFactoryClass", - "org.datanucleus.api.jdo.JDOPersistenceManagerFactory"); - - postgresContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:11-alpine")); - postgresContainer.start(); - - jdbi = Jdbi.create( - postgresContainer.getJdbcUrl(), - postgresContainer.getUsername(), - postgresContainer.getPassword()); - } - - @After - public void tearDown() { - if (postgresContainer != null) { - postgresContainer.stop(); - } - } - - // @BeforeClass - // public static void beforeClass() { - // Config.enableUnitTests(); - // } - - // @AfterClass - // public static void afterClass() { - // KafkaProducerInitializer.tearDown(); - // } - - // @Rule - // public WireMockRule wireMockRule = new WireMockRule(); - - @Test - public void testGetUserProjectPermissions() throws ParseException { - final var configMock = mock(Config.class); - when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_URL))).thenReturn(postgresContainer.getJdbcUrl()); - when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_DRIVER))) - .thenReturn(postgresContainer.getDriverClassName()); - when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_USERNAME))) - .thenReturn(postgresContainer.getUsername()); - when(configMock.getProperty(eq(Config.AlpineKey.DATABASE_PASSWORD))) - .thenReturn(postgresContainer.getPassword()); - when(configMock.getPropertyAsBoolean(eq(ConfigKey.INIT_TASKS_ENABLED))).thenReturn(true); - when(configMock.getPropertyAsBoolean(eq(ConfigKey.DATABASE_RUN_MIGRATIONS))).thenReturn(true); - - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var readPermission = new Permission(); - readPermission.setId(1); - readPermission.setName("read"); - readPermission.setDescription("permission to read"); - qm.persist(readPermission); - - final var writePermission = new Permission(); - writePermission.setId(2); - writePermission.setName("write"); - writePermission.setDescription("permission to write"); - qm.persist(writePermission); - - List expectedPermissionsList = Arrays.asList( - readPermission, - writePermission); - - Set expectedPermissions = new HashSet<>(expectedPermissionsList); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); - qm.persist(testUser); - - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - maintainerRole.setPermissions(expectedPermissions); - qm.persist(maintainerRole); - - // final var ldapUserProjectRole = new LdapUserProjectRole(); - // ldapUserProjectRole.setProject(testProject); - - final var managedUserProjectRole = new ManagedUserProjectRole(); - // managedUserProjectRole.setId(1); - managedUserProjectRole.setProject(testProject); - managedUserProjectRole.setManagedUsers(Arrays.asList(testUser)); - managedUserProjectRole.setRole(maintainerRole); - // qm.persist(managedUserProjectRole); - - // final var oidcUserProjectRole = new OidcUserProjectRole(); - - List actualPermissions = qm.getUserProjectPermissions("test-user", "test-project"); - - Assert.assertEquals(actualPermissions, expectedPermissionsList); - } - -} From 38dfe4f484c0b056d586f481ab6e14fdd085d8ff Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Tue, 1 Apr 2025 18:28:50 -0500 Subject: [PATCH 17/45] refactor: add triggers to update effective permissions table with role changes (#18) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../migration/changelog-v5.6.0-roles.xml | 470 ++++++++++++++++++ 1 file changed, 470 insertions(+) create mode 100644 src/main/resources/migration/changelog-v5.6.0-roles.xml diff --git a/src/main/resources/migration/changelog-v5.6.0-roles.xml b/src/main/resources/migration/changelog-v5.6.0-roles.xml new file mode 100644 index 0000000000..fa21c426c8 --- /dev/null +++ b/src/main/resources/migration/changelog-v5.6.0-roles.xml @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- Helper function to recalculate all user permissions for a project. + -- Called by trigger functions to update the values in the USER_PROJECT_EFFECTIVE_PERMISSIONS table. + CREATE OR REPLACE FUNCTION recalc_user_project_role_effective_permissions(project_ids BIGINT[]) + RETURNS void AS $$ + DECLARE + tbl_prefix TEXT; + BEGIN + -- Remove any existing effective permissions for this project + DELETE FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" + WHERE "PROJECT_ID" = ANY(project_ids); + + -- Rebuild effective permissions for all user types + FOREACH tbl_prefix IN ARRAY ARRAY['LDAP', 'MANAGED', 'OIDC'] + LOOP + EXECUTE format($query$ + INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" + (%I, "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") + SELECT DISTINCT upr.%I, upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" + FROM %I upr + INNER JOIN "ROLES_PERMISSIONS" rp + ON rp."ROLE_ID" = upr."ROLE_ID" + INNER JOIN "PERMISSION" p + ON p."ID" = rp."PERMISSION_ID" + WHERE upr."PROJECT_ID" = ANY($1); + $query$, + tbl_prefix || 'USER_ID', + tbl_prefix || 'USER_ID', + tbl_prefix || 'USERS_PROJECTS_ROLES') + USING project_ids; + END LOOP; + END; + $$ LANGUAGE plpgsql; + + + + CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_delete() + RETURNS TRIGGER AS $$ + DECLARE + project_ids BIGINT[]; + role_ids BIGINT[]; + BEGIN + SELECT ARRAY_AGG(DISTINCT "ROLE_ID") + INTO role_ids + FROM old_table; + + IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN + SELECT ARRAY_AGG(sub."PROJECT_ID") + INTO project_ids + FROM ( + SELECT lpr."PROJECT_ID" + FROM "LDAPUSERS_PROJECTS_ROLES" lpr + INNER JOIN old_table + ON old_table."ROLE_ID" = lpr."ROLE_ID" + UNION + SELECT mpr."PROJECT_ID" + FROM "MANAGEDUSERS_PROJECTS_ROLES" mpr + INNER JOIN old_table + ON old_table."ROLE_ID" = mpr."ROLE_ID" + UNION + SELECT opr."PROJECT_ID" + FROM "OIDCUSERS_PROJECTS_ROLES" opr + INNER JOIN old_table + ON old_table."ROLE_ID" = opr."ROLE_ID" + ) sub; + ELSE + EXECUTE format($query$ + SELECT ARRAY_AGG(DISTINCT t."PROJECT_ID") + FROM %I AS t + WHERE t."ROLE_ID" = ANY($1) + $query$, TG_TABLE_NAME) + USING role_ids + INTO project_ids; + END IF; + + PERFORM recalc_user_project_role_effective_permissions(project_ids); + RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + + + CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_insert() + RETURNS TRIGGER AS $$ + DECLARE + project_ids BIGINT[]; + role_ids BIGINT[]; + BEGIN + SELECT ARRAY_AGG(DISTINCT "ROLE_ID") + INTO role_ids + FROM new_table; + + IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN + SELECT ARRAY_AGG(sub."PROJECT_ID") + INTO project_ids + FROM ( + SELECT lpr."PROJECT_ID" + FROM "LDAPUSERS_PROJECTS_ROLES" lpr + INNER JOIN new_table + ON new_table."ROLE_ID" = lpr."ROLE_ID" + UNION + SELECT mpr."PROJECT_ID" + FROM "MANAGEDUSERS_PROJECTS_ROLES" mpr + INNER JOIN new_table + ON new_table."ROLE_ID" = mpr."ROLE_ID" + UNION + SELECT opr."PROJECT_ID" + FROM "OIDCUSERS_PROJECTS_ROLES" opr + INNER JOIN new_table + ON new_table."ROLE_ID" = opr."ROLE_ID" + ) sub; + ELSE + EXECUTE format($query$ + SELECT ARRAY_AGG(DISTINCT t."PROJECT_ID") + FROM %I AS t + WHERE t."ROLE_ID" = ANY($1) + $query$, TG_TABLE_NAME) + USING role_ids + INTO project_ids; + END IF; + + PERFORM recalc_user_project_role_effective_permissions(project_ids); + RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + + + CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_update() + RETURNS TRIGGER AS $$ + DECLARE + project_ids BIGINT[]; + role_ids BIGINT[]; + BEGIN + SELECT ARRAY_AGG("ROLE_ID") + INTO role_ids + FROM ( + SELECT "ROLE_ID" FROM old_table + UNION + SELECT "ROLE_ID" FROM new_table + ) roles; + + IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN + SELECT ARRAY_AGG(sub."PROJECT_ID") + INTO project_ids + FROM ( + SELECT lpr."PROJECT_ID" + FROM "LDAPUSERS_PROJECTS_ROLES" lpr + INNER JOIN new_table + ON new_table."ROLE_ID" = lpr."ROLE_ID" + FULL OUTER JOIN old_table + ON new_table."ROLE_ID" = old_table."ROLE_ID" + UNION + SELECT mpr."PROJECT_ID" + FROM "MANAGEDUSERS_PROJECTS_ROLES" mpr + INNER JOIN new_table + ON new_table."ROLE_ID" = mpr."ROLE_ID" + FULL OUTER JOIN old_table + ON new_table."ROLE_ID" = old_table."ROLE_ID" + UNION + SELECT opr."PROJECT_ID" + FROM "OIDCUSERS_PROJECTS_ROLES" opr + INNER JOIN new_table + ON new_table."ROLE_ID" = opr."ROLE_ID" + FULL OUTER JOIN old_table + ON new_table."ROLE_ID" = old_table."ROLE_ID" + ) sub; + ELSE + EXECUTE format($query$ + SELECT ARRAY_AGG(DISTINCT t."PROJECT_ID") + FROM %I AS t + WHERE t."ROLE_ID" = ANY($1) + $query$, TG_TABLE_NAME) + USING role_ids + INTO project_ids; + END IF; + + PERFORM recalc_user_project_role_effective_permissions(project_ids); + RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + + + -- INSERT trigger for LDAPUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_roles_insert + AFTER INSERT ON "LDAPUSERS_PROJECTS_ROLES" + REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); + + -- DELETE trigger for LDAPUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_roles_delete + AFTER DELETE ON "LDAPUSERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); + + -- UPDATE trigger for LDAPUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_roles_update + AFTER UPDATE ON "LDAPUSERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_update(); + + -- INSERT trigger for MANAGEDUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_mgdusers_roles_insert + AFTER INSERT ON "MANAGEDUSERS_PROJECTS_ROLES" + REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); + + -- DELETE trigger for MANAGEDUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_mgdusers_roles_delete + AFTER DELETE ON "MANAGEDUSERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); + + -- UPDATE trigger for MANAGEDUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_mgdusers_roles_update + AFTER UPDATE ON "MANAGEDUSERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_update(); + + -- INSERT trigger for OIDCUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_roles_insert + AFTER INSERT ON "OIDCUSERS_PROJECTS_ROLES" + REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); + + -- DELETE trigger for OIDCUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_roles_delete + AFTER DELETE ON "OIDCUSERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); + + -- UPDATE trigger for OIDCUSERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_roles_update + AFTER UPDATE ON "OIDCUSERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_update(); + + -- INSERT trigger for ROLES_PERMISSIONS + CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_insert + AFTER INSERT ON "ROLES_PERMISSIONS" + REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); + + -- DELETE trigger for ROLES_PERMISSIONS + CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_delete + AFTER DELETE ON "ROLES_PERMISSIONS" + REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); + + -- UPDATE trigger for ROLES_PERMISSIONS + CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_update + AFTER UPDATE ON "ROLES_PERMISSIONS" + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION effective_permissions_mx_on_update(); + + + From 29a21fc59887f4bb6f1fbfaa6af167b4c9b296e6 Mon Sep 17 00:00:00 2001 From: lmphil <126618132+lmphil@users.noreply.github.com> Date: Wed, 7 May 2025 18:38:35 -0400 Subject: [PATCH 18/45] test: add unit tests for RoleQueryManager class (#19) Signed-off-by: lmphil <126618132+lmphil@users.noreply.github.com> --- .../persistence/RoleQueryManager.java | 97 ++++ .../persistence/jdbi/RoleDao.java | 44 +- .../persistence/RoleQueryManagerTest.java | 421 ++++++++++++++++++ 3 files changed, 542 insertions(+), 20 deletions(-) create mode 100644 apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 94dae4f731..55a77e205e 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -59,4 +59,101 @@ boolean removeRoleFromUser(UserPrincipal principal, Role role, String roleName, //TODO: Implement removeRoleFromUser return true; } + + public List getUnassignedRolePermissions(final Role role) { + final List permissions = new ArrayList<>(); + + final var permissionNames = role.getPermissions().stream() + .map(Permission::getName) + .toList(); + + final Query query = pm.newQuery(Permission.class) + .filter("!:permissionNames.contains(name)") + .setNamedParameters(Map.of("permissionNames", permissionNames)); + + permissions.addAll(executeAndCloseList(query)); + + return permissions; + } + + @Override + public Role updateRole(final Role transientRole) { + final Role role = getObjectByUuid(Role.class, transientRole.getUuid()); + if (role == null) + return null; + + role.setName(transientRole.getName()); + + return persist(role); + } + + @Override + public List getUserProjectPermissions(final String username, final String projectName) { + final UserPrincipal user = getUserPrincipal(username); + final String columnName; + + switch (user) { + case LdapUser ldapUser -> columnName = "LDAPUSER_ID"; + case ManagedUser managedUser -> columnName = "MANAGEDUSER_ID"; + case OidcUser oidcUser -> columnName = "OIDCUSER_ID"; + default -> { + return null; + } + } + + final Query projectsQuery = pm.newQuery(Project.class) + .filter("name == :projectName") + .setNamedParameters(Map.of("projectName", projectName)); + + final String projectIds = executeAndCloseList(projectsQuery).stream() + .map(Project::getId) + .map(String::valueOf) + .collect(Collectors.joining(", ", "(", ")")); + + // language=SQL + final var queryString = """ + SELECT + upep."LDAPUSER_ID", + upep."MANAGEDUSER_ID", + upep."OIDCUSER_ID", + upep."PROJECT_ID", + upep."PERMISSION_ID", + upep."PERMISSION_NAME" + FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" upep + WHERE upep."%s" = :userId + AND upep."PROJECT_ID" IN %s + """.formatted(columnName, projectIds); + + final Query query = pm.newQuery(Query.SQL, queryString); + query.setNamedParameters(Map.of( + "userId", user.getId(), + "projectIds", projectIds)); + + return executeAndCloseResultList(query, UserProjectEffectivePermissionsRow.class) + .stream() + .map(UserProjectEffectivePermissionsRow::permissionName) + .map(this::getPermission) + .distinct() + .toList(); + } + + @Override + public boolean addRoleToUser(final UserPrincipal user, final Role role, final Project project) { + return JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addRoleToUser( + user.getClass(), + user.getId(), + project.getId(), + role.getId())) == 1; + } + + @Override + public boolean removeRoleFromUser(final UserPrincipal user, final Role role, final Project project) { + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser( + user.getClass(), + user.getId(), + project.getName(), + role.getId())) > 0; + } + } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java index 0ce3d1ac77..0a99b80359 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -34,28 +34,32 @@ public interface RoleDao { int deleteRole(@Bind final long roleId); @SqlUpdate(/* language=sql */ """ - DELETE - FROM "LDAPUSERS_PROJECTS_ROLES" - WHERE "LDAPUSER_ID" = :userId - AND "PROJECT_ACCESS_ROLE_ID" IN ( - SELECT "ID" - FROM "PROJECT_ACCESS_ROLES" - WHERE "ROLE_ID" = :roleId - AND "PROJECT_ID" = :projectId) - """) - int removeRoleFromLdapUser(@Bind final long userId, @Bind final long projectId, @Bind final long roleId); + INSERT INTO "ROLES_PERMISSIONS" + ("ROLE_ID", "PERMISSION_ID") + VALUES + (:roleId, :permissionId) + ON CONFLICT DO NOTHING + """) + @DefineNamedBindings + int addPermissionToRole( + @Bind long roleId, + @Bind long permissionId); @SqlUpdate(/* language=sql */ """ - DELETE - FROM "MANAGEDUSERS_PROJECTS_ROLES" - WHERE "MANAGEDUSER_ID" = :userId - AND "PROJECT_ACCESS_ROLE_ID" IN ( - SELECT "ID" - FROM "PROJECT_ACCESS_ROLES" - WHERE "ROLE_ID" = :roleId - AND "PROJECT_ID" = :projectId) - """) - int removeRoleFromManagedUser(@Bind final long userId, @Bind final long projectId, @Bind final long roleId); + <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> + <#assign prefix = userClass.getSimpleName()?upper_case> + INSERT INTO "${prefix}S_PROJECTS_ROLES" + ("${prefix}_ID", "PROJECT_ID", "ROLE_ID") + VALUES + (:userId, :projectId, :roleId) + ON CONFLICT DO NOTHING + """) + @DefineNamedBindings + int addRoleToUser( + @Define Class userClass, + @Bind long userId, + @Bind long projectId, + @Bind long roleId); @SqlUpdate(/* language=sql */ """ DELETE diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java new file mode 100644 index 0000000000..142269eb8e --- /dev/null +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -0,0 +1,421 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence; + +import org.dependencytrack.model.Project; +import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.Role; +import org.dependencytrack.persistence.jdbi.JdbiFactory; +import org.dependencytrack.persistence.jdbi.RoleDao; +import org.jdbi.v3.core.Jdbi; + +import alpine.model.ManagedUser; +import alpine.model.Permission; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import org.dependencytrack.PersistenceCapableTest; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.utility.DockerImageName; + +import static org.assertj.core.api.Assertions.assertThat; + +public class RoleQueryManagerTest extends PersistenceCapableTest { + + private PostgreSQLContainer postgresContainer; + private Jdbi jdbi; + + @Before + public void setUp() { + System.setProperty("javax.jdo.PersistenceManagerFactoryClass", + "org.datanucleus.api.jdo.JDOPersistenceManagerFactory"); + + postgresContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:11-alpine")); + postgresContainer.start(); + + jdbi = Jdbi.create( + postgresContainer.getJdbcUrl(), + postgresContainer.getUsername(), + postgresContainer.getPassword()); + } + + @After + public void tearDown() { + if (postgresContainer != null) { + postgresContainer.stop(); + } + } + + @Test + public void testCreateRole() { + final var readPermission = new Permission(); + readPermission.setId(1); + readPermission.setName("read"); + readPermission.setDescription("permission to read"); + qm.persist(readPermission); + + final var writePermission = new Permission(); + writePermission.setId(2); + writePermission.setName("write"); + writePermission.setDescription("permission to write"); + qm.persist(writePermission); + + List expectedPermissionsList = Arrays.asList( + readPermission, + writePermission); + + assertThat(qm.createRole("maintainer", expectedPermissionsList)).satisfies( + roleCreated -> assertThat(roleCreated.getName()).isEqualTo("maintainer")); + } + + @Test + public void testGetRoles() { + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); + + final var ownerRole = new Role(); + ownerRole.setId(2); + ownerRole.setName("owner"); + qm.persist(ownerRole); + + List expectedRoles = Arrays.asList( + maintainerRole, + ownerRole); + + List actualRoles = qm.getRoles(); + List actualRolesMutable = new ArrayList(); + for (Role r : actualRoles) { + actualRolesMutable.add(r); + } + + Assert.assertEquals(expectedRoles, actualRolesMutable); + } + + @Test + public void testGetRole() { + final var wrongRole = new Role(); + wrongRole.setId(1); + wrongRole.setName("maintainer"); + qm.persist(wrongRole); + + final var expectedRole = new Role(); + expectedRole.setId(2); + expectedRole.setName("owner"); + qm.persist(expectedRole); + + String expectedRoleUuid = expectedRole.getUuid().toString(); + + Role actualRole = qm.getRole(expectedRoleUuid); + + Assert.assertEquals(expectedRole, actualRole); + } + + @Test + public void testGetUserRoles() throws ParseException { + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + qm.persist(testUser); + + final var expectedRole = new Role(); + expectedRole.setId(1); + expectedRole.setName("maintainer"); + qm.persist(expectedRole); + + JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addRoleToUser( + testUser.getClass(), + testUser.getId(), + testProject.getId(), + expectedRole.getId())); + + List actualRoles = qm.getUserRoles(testUser); + + Assert.assertEquals(actualRoles.size(), 1); + Assert.assertEquals(expectedRole.toString(), actualRoles.get(0).getRole().toString()); + } + + @Test + public void testGetUnassignedProjects() throws ParseException { + String testUserName = "test-user"; + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername(testUserName); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + qm.persist(testUser); + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); + + final var unassignedProject1 = new Project(); + unassignedProject1.setId(1); + unassignedProject1.setName("test-project-1"); + qm.persist(unassignedProject1); + + final var assignedProject = new Project(); + assignedProject.setId(2); + assignedProject.setName("test-project-2"); + + qm.persist(assignedProject); + + final var unassignedProject2 = new Project(); + unassignedProject2.setId(3); + unassignedProject2.setName("test-project-3"); + qm.persist(unassignedProject2); + + JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addRoleToUser( + testUser.getClass(), + testUser.getId(), + assignedProject.getId(), + maintainerRole.getId())); + + List expectedProjects = Arrays.asList( + unassignedProject1, + unassignedProject2); + + List actualProjects = qm.getUnassignedProjects(testUserName); + + Assert.assertEquals(expectedProjects.toString(), actualProjects.toString()); + } + + @Test + public void testGetUnassignedRolePermissions() throws ParseException { + final var readPermission = new Permission(); + readPermission.setId(1); + readPermission.setName("read"); + readPermission.setDescription("permission to read"); + qm.persist(readPermission); + + final var writePermission = new Permission(); + writePermission.setId(2); + writePermission.setName("write"); + writePermission.setDescription("permission to write"); + qm.persist(writePermission); + + final var partyPermission = new Permission(); + partyPermission.setId(3); + partyPermission.setName("party"); + partyPermission.setDescription("permission to party"); + qm.persist(partyPermission); + + List expectedPermissionsList = Arrays.asList( + readPermission, + writePermission); + + Set allPermissions = new HashSet<>(Arrays.asList( + writePermission, + writePermission, + partyPermission)); + + final var assistantRegionalManagerRole = new Role(); + assistantRegionalManagerRole.setId(1); + assistantRegionalManagerRole.setName("maintainer"); + assistantRegionalManagerRole.setPermissions(allPermissions); + qm.persist(assistantRegionalManagerRole); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + testUser.setPermissions(expectedPermissionsList); + qm.persist(testUser); + + List actualPermissions = qm.getUnassignedRolePermissions(assistantRegionalManagerRole); + + Assert.assertEquals(actualPermissions.size(), 1); + Assert.assertEquals(expectedPermissionsList.get(0), actualPermissions.get(0)); + } + + @Test + public void testUpdateRole() { + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); + + Role actualRole = qm.updateRole(maintainerRole); + + Assert.assertEquals(maintainerRole, actualRole); + + // TODO: Check requirements of `updateRole`. + } + + @Test + public void testGetUserProjectPermissions() throws ParseException { + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var readPermission = new Permission(); + readPermission.setId(1); + readPermission.setName("read"); + readPermission.setDescription("permission to read"); + qm.persist(readPermission); + + final var writePermission = new Permission(); + writePermission.setId(2); + writePermission.setName("write"); + writePermission.setDescription("permission to write"); + qm.persist(writePermission); + + List expectedPermissionsList = Arrays.asList( + readPermission, + writePermission); + + Set expectedPermissions = new HashSet<>(expectedPermissionsList); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + testUser.setPermissions(expectedPermissionsList); + qm.persist(testUser); + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + maintainerRole.setPermissions(expectedPermissions); + qm.persist(maintainerRole); + + JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addPermissionToRole( + maintainerRole.getId(), + readPermission.getId())); + + JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addPermissionToRole( + maintainerRole.getId(), + writePermission.getId())); + + JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addRoleToUser( + testUser.getClass(), + testUser.getId(), + testProject.getId(), + maintainerRole.getId())); + + List actualPermissions = qm.getUserProjectPermissions("test-user", "test-project"); + List actualPermissionsSorted = new ArrayList(); + for (Permission p : actualPermissions) { + actualPermissionsSorted.add(p); + } + Collections.sort(actualPermissionsSorted, Comparator.comparing(Permission::getId)); + + Assert.assertEquals(expectedPermissionsList, actualPermissionsSorted); + } + + @Test + public void testAddRoleToUser() throws ParseException { + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + qm.persist(testUser); + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); + + qm.addRoleToUser(testUser, maintainerRole, testProject); + } + + @Test + public void testRemoveRoleFromUser() throws ParseException { + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + qm.persist(testUser); + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); + + JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addRoleToUser( + testUser.getClass(), + testUser.getId(), + testProject.getId(), + maintainerRole.getId())); + + Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); + } +} From 4dc0e7700dc80ea0a0dc69ec079319c8cb49e8da Mon Sep 17 00:00:00 2001 From: lmphil <126618132+lmphil@users.noreply.github.com> Date: Wed, 7 May 2025 13:59:22 -0400 Subject: [PATCH 19/45] test: add RoleResource unit tests (#20) Signed-off-by: lmphil <126618132+lmphil@users.noreply.github.com> --- .../resources/v1/RoleResourceTest.java | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java new file mode 100644 index 0000000000..ccc9e220ba --- /dev/null +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -0,0 +1,192 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.resources.v1; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.dependencytrack.JerseyTestRule; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Role; +import org.dependencytrack.ResourceTest; +import org.dependencytrack.auth.Permissions; +import org.dependencytrack.persistence.DefaultObjectGenerator; +import org.dependencytrack.persistence.jdbi.JdbiFactory; +import org.dependencytrack.persistence.jdbi.RoleDao; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.server.ResourceConfig; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +import alpine.common.util.UuidUtil; +import alpine.model.ManagedUser; +import alpine.model.Permission; +import alpine.server.filters.ApiFilter; +import alpine.server.filters.AuthenticationFilter; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; + +public class RoleResourceTest extends ResourceTest { + + @ClassRule + public static JerseyTestRule jersey = new JerseyTestRule( + new ResourceConfig(RoleResource.class) + .register(ApiFilter.class) + .register(AuthenticationFilter.class)); + + @Before + @Override + public void before() throws Exception { + super.before(); + final var generator = new DefaultObjectGenerator(); + generator.loadDefaultRoles(); + } + + @Test + public void getRolesTest() { + Response response = jersey.target(V1_ROLE).request() + .header(X_API_KEY, apiKey) + .get(Response.class); + Assert.assertEquals(200, response.getStatus(), 0); + JsonArray json = parseJsonArray(response); + Assert.assertNotNull(json); + Assert.assertEquals(4, json.size()); + for (int i = 0; i < json.size(); i++) { + Assert.assertNotNull(json.getJsonObject(i).getString("name")); + Assert.assertNotNull(json.getJsonObject(i).getString("uuid")); + } + } + + @Test + public void getRoleTest() { + List rolePermissions = new ArrayList(); + Role role = qm.createRole("ABC", rolePermissions); + Response response = jersey.target(V1_ROLE + "/" + role.getUuid()).request() + .header(X_API_KEY, apiKey) + .get(Response.class); + Assert.assertEquals(200, response.getStatus(), 0); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("ABC", json.getString("name")); + } + + @Test + public void getRoleByInvalidUuidTest() { + Response response = jersey.target(V1_ROLE + "/" + UUID.randomUUID()) + .request().header(X_API_KEY, apiKey).get(Response.class); + Assert.assertEquals(404, response.getStatus(), 0); + Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); + String body = getPlainTextBody(response); + Assert.assertEquals("The role could not be found.", body); + } + + @Test + public void createRoleTest() { + initializeWithPermissions(Permissions.ROLE_MANAGEMENT_CREATE); + + Response response = jersey.target(V1_ROLE).request() + .header(X_API_KEY, apiKey) + .put(Entity.json(/* language=JSON */ """ + { + "name": "ABC", + "permissions": [] + } + """)); + Assert.assertEquals(201, response.getStatus()); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("ABC", json.getString("name")); + Assert.assertTrue(UuidUtil.isValidUUID(json.getString("uuid"))); + } + + @Test + public void updateRoleTest() { + List rolePermissions = new ArrayList(); + Role role = qm.createRole("My Role", rolePermissions); + role.setName("My New Role Name"); + Response response = jersey.target(V1_ROLE).request() + .header(X_API_KEY, apiKey) + .post(Entity.entity(role, MediaType.APPLICATION_JSON)); + Assert.assertEquals(200, response.getStatus(), 0); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("My New Role Name", json.getString("name")); + } + + @Test + public void deleteRoleTest() { + List rolePermissions = new ArrayList(); + Role role = qm.createRole("My Role", rolePermissions); + Response response = jersey.target(V1_ROLE).request() + .header(X_API_KEY, apiKey) + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) // HACK + .method("DELETE", Entity.entity(role, MediaType.APPLICATION_JSON)); // HACK + // Hack: Workaround to https://github.com/eclipse-ee4j/jersey/issues/3798 + Assert.assertEquals(204, response.getStatus(), 0); + } + + @Test + public void getUserRolesTest() throws ParseException { + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword("password"); + qm.persist(testUser); + + final var expectedRole = new Role(); + expectedRole.setId(1); + expectedRole.setName("maintainer"); + qm.persist(expectedRole); + + JdbiFactory.withJdbiHandle( + handle -> handle.attach(RoleDao.class).addRoleToUser( + testUser.getClass(), + testUser.getId(), + testProject.getId(), + expectedRole.getId())); + + Response response = jersey.target(V1_ROLE + "/test-user/roles").request() + .header(X_API_KEY, apiKey) + .get(Response.class); + Assert.assertEquals(200, response.getStatus(), 0); + JsonArray json = parseJsonArray(response); + Assert.assertNotNull(json); + Assert.assertEquals(1, json.size()); + Assert.assertEquals("maintainer", json.getJsonObject(0).getJsonObject("role").getString("name")); + } + +} From ba28c801f3694f8078c171bc08f97fa3fd973b40 Mon Sep 17 00:00:00 2001 From: Alexis Lamb Date: Wed, 30 Apr 2025 14:52:15 -0400 Subject: [PATCH 20/45] Update createRole API to create a new role with permissions (#22) Signed-off-by: Alexis Lamb --- .../persistence/QueryManager.java | 4 ++ .../persistence/RoleQueryManager.java | 19 +++++- .../resources/v1/RoleResource.java | 64 +++++++++++++++---- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index d395b5c20c..e8e38d8842 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -889,6 +889,10 @@ public List getRoles() { return getRoleQueryManager().getRoles(); } + public Role getRoleByName(String name) { + return getRoleQueryManager().getRoleByName(name); + } + public Role getRole(String uuid) { return getRoleQueryManager().getRole(uuid); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 55a77e205e..e59781de08 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -8,6 +8,8 @@ import org.dependencytrack.model.Role; +import org.apache.commons.lang3.StringUtils; + import alpine.common.logging.Logger; import alpine.resources.AlpineRequest; @@ -33,9 +35,20 @@ public List getRoles() { return Collections.emptyList(); } - public Role getRole(String uuid) { - // TODO:Implement role retrieval logic - return null; + @Override + public Role getRoleByName(final String name) { + final String role = StringUtils.lowerCase(StringUtils.trimToNull(name)); + final Query query = pm.newQuery(Role.class) + .filter("name.toLowerCase().trim() == :name") + .setNamedParameters(Map.of("name", role)) + .range(0, 1); + + return executeAndCloseUnique(query); + } + + @Override + public Role getRole(final String uuid) { + return getObjectByUuid(Role.class, uuid, Role.FetchGroup.ALL.name()); } public Role updateRole(Role role) { diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index c406cd3f6f..40c19a26f8 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -36,6 +36,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.security.SecurityRequirements; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DELETE; import jakarta.ws.rs.GET; @@ -51,11 +52,21 @@ import org.dependencytrack.model.validation.ValidUuid; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.persistence.jdbi.RoleDao; +import org.dependencytrack.resources.v1.vo.CreateRoleRequest; + import org.jdbi.v3.core.Handle; import org.owasp.security.logging.SecurityMarkers; +import alpine.model.Permission; +import alpine.model.UserPrincipal; + import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; +import java.util.List; +import java.util.Map; + +import javax.jdo.Query; + /** * JAX-RS resources for processing roles. * @@ -127,22 +138,41 @@ public Response getRole( @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Operation( - summary = "Creates a new role", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_CREATE

") + @Operation(summary = "Creates a new role", description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_CREATE

") @ApiResponses(value = { - @ApiResponse( - responseCode = "201", - description = "The created role", - content = @Content(schema = @Schema(implementation = Role.class))), - @ApiResponse(responseCode = "401", description = "Unauthorized") + @ApiResponse(responseCode = "201", description = "The created role", content = @Content(schema = @Schema(implementation = Role.class))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "409", description = "The Role already exists"), }) - @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_CREATE}) - public Response createRole(Role jsonRole) { - failOnValidationError(super.getValidator().validateProperty(jsonRole, "name")); - + @PermissionRequired({ Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_CREATE }) + public Response createRole(@Valid CreateRoleRequest request) { try (QueryManager qm = new QueryManager()) { - final Role role = qm.createRole(jsonRole.getName(), jsonRole.getPermissions().stream().toList()); + boolean roleExists = qm.getRoleByName(request.name()) != null; + + if (roleExists) { + return Response.status(Response.Status.CONFLICT) + .entity(String.format("Role '%s' already exists", request.name())) + .build(); + } + + List permissionNames = request.permissions() + .stream() + .map(Permissions::name) + .toList(); + + final Query query = qm.getPersistenceManager().newQuery(Permission.class) + .filter(":permissions.contains(name)") + .setNamedParameters(Map.of("permissions", permissionNames)) + .orderBy("name asc"); + + final List requestedPermissions; + try { + requestedPermissions = List.copyOf(query.executeList()); + } finally { + query.closeAll(); + } + + final Role role = qm.createRole(request.name(), requestedPermissions); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Role created: " + role.getName()); return Response.status(Response.Status.CREATED).entity(role).build(); @@ -207,5 +237,13 @@ public Response deleteRole(Role jsonRole) { } + List roles = qm.getUserRoles(principal); + if (roles == null || roles.isEmpty()) { + LOGGER.info("No roles found for user: " + username); + return Response.ok(List.of()).build(); + } + return Response.ok(roles).build(); + } + } } From 90bd7686ea7ea1c46f96c3616a1eb2f4b5c1539c Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Mon, 12 May 2025 11:50:21 -0500 Subject: [PATCH 21/45] Merge pull request #23 from jhoward-lm/roles-consolidate-user-tables Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- .../main/java/alpine/model/Permission.java | 2 +- .../src/main/java/alpine/model/Team.java | 3 +- apiserver/pom.xml | 4 +- .../dependencytrack/model/ProjectRole.java | 180 ++------ .../persistence/QueryManager.java | 39 +- .../persistence/RoleQueryManager.java | 38 +- .../persistence/jdbi/RoleDao.java | 81 +++- .../jdbi/mapping/ProjectRoleRowMapper.java | 43 +- .../resources/v1/AccessControlResource.java | 6 +- .../resources/v1/RoleResource.java | 27 +- .../resources/v1/UserResource.java | 114 +++-- .../main/resources/META-INF/persistence.xml | 4 +- .../persistence/RoleQueryManagerTest.java | 11 +- .../v1/NotificationRuleResourceTest.java | 3 +- .../resources/v1/PermissionResourceTest.java | 2 +- .../resources/v1/RoleResourceTest.java | 3 +- .../resources/v1/TeamResourceTest.java | 2 +- .../resources/migration/changelog-v5.6.0.xml | 397 ------------------ .../migration/changelog-v5.6.0-roles.xml | 301 +++---------- 19 files changed, 319 insertions(+), 941 deletions(-) diff --git a/alpine/alpine-model/src/main/java/alpine/model/Permission.java b/alpine/alpine-model/src/main/java/alpine/model/Permission.java index 01b0c074dd..87edb5df62 100644 --- a/alpine/alpine-model/src/main/java/alpine/model/Permission.java +++ b/alpine/alpine-model/src/main/java/alpine/model/Permission.java @@ -45,7 +45,7 @@ * @since 1.0.0 */ @PersistenceCapable -@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class Permission implements Serializable { private static final long serialVersionUID = 1420020753285692448L; diff --git a/alpine/alpine-model/src/main/java/alpine/model/Team.java b/alpine/alpine-model/src/main/java/alpine/model/Team.java index 57b58b2492..247993f55a 100644 --- a/alpine/alpine-model/src/main/java/alpine/model/Team.java +++ b/alpine/alpine-model/src/main/java/alpine/model/Team.java @@ -60,7 +60,7 @@ @Persistent(name = "mappedOidcGroups"), @Persistent(name = "permissions") }) -@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public class Team implements Serializable { private static final long serialVersionUID = 6938424919898277944L; @@ -97,7 +97,6 @@ public enum FetchGroup { @Persistent(mappedBy = "teams") @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - @JsonIgnore private List users; @Persistent(mappedBy = "team") diff --git a/apiserver/pom.xml b/apiserver/pom.xml index b7c3ccb8cc..218d133081 100644 --- a/apiserver/pom.xml +++ b/apiserver/pom.xml @@ -43,8 +43,8 @@ 0.5.3.2 3.2.4 2.3.0 - 2.2.32 - 2.1.28 + 2.2.30 + 2.1.27 1.19.0 0.7.0 7.1.0 diff --git a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java index 32be80ee8a..2c4d79fbae 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java @@ -21,9 +21,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; -import alpine.model.LdapUser; -import alpine.model.ManagedUser; -import alpine.model.OidcUser; +import alpine.model.User; import java.io.Serializable; import java.util.ArrayList; @@ -37,7 +35,6 @@ import javax.jdo.annotations.Extension; import javax.jdo.annotations.FetchGroup; import javax.jdo.annotations.Order; -import javax.jdo.annotations.PersistenceAware; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.Unique; @@ -48,9 +45,15 @@ * @author Jonathan Howard * @since 5.6.0 */ -@PersistenceAware +@PersistenceCapable(table = "USERS_PROJECTS_ROLES") @JsonInclude(JsonInclude.Include.NON_NULL) -public abstract class ProjectRole implements Serializable { +@Unique(name = "USERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "users", "project", "role" }) +@FetchGroup(name = "ALL", members = { + @Persistent(name = "role"), + @Persistent(name = "project"), + @Persistent(name = "users") +}) +public class ProjectRole implements Serializable { @Persistent(defaultFetchGroup = "true") @Column(name = "ROLE_ID", allowsNull = "false") @@ -62,6 +65,27 @@ public abstract class ProjectRole implements Serializable { @JsonIgnore private Project project; + @Persistent(defaultFetchGroup = "true") + @Column(name = "USER_ID", allowsNull = "false") + @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + private List users; + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + + public void addUsers(User... users) { + this.users = Objects.requireNonNullElse(this.users, new ArrayList()); + this.users = Stream.concat(this.users.stream(), Arrays.stream(users)) + .distinct() + .sorted(Comparator.comparing(User::getUsername)) + .toList(); + } + public Role getRole() { return role; } @@ -78,148 +102,4 @@ public void setProject(Project project) { this.project = project; } - /** - * Model for associating a role on a given project with LDAP users. - * - * @author Allen Shearin - * @since 5.6.0 - */ - @PersistenceCapable(table = "LDAPUSERS_PROJECTS_ROLES") - @Unique(name = "LDAPUSERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "ldapUsers", "project", "role" }) - @FetchGroup(name = "ALL", members = { - @Persistent(name = "role"), - @Persistent(name = "project"), - @Persistent(name = "ldapUsers") - }) - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class LdapUserProjectRole extends ProjectRole { - - private static final long serialVersionUID = 6018553054343647649L; - - /** - * Defines JDO fetch groups for this class. - */ - public enum FetchGroup { - ALL - } - - @Persistent(defaultFetchGroup = "true") - @Column(name = "LDAPUSER_ID", allowsNull = "false") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - private List ldapUsers; - - public List getLdapUsers() { - return ldapUsers; - } - - public void setLdapUsers(List ldapUsers) { - this.ldapUsers = ldapUsers; - } - - public void addLdapUsers(LdapUser... ldapUsers) { - this.ldapUsers = Objects.requireNonNullElse(this.ldapUsers, new ArrayList()); - this.ldapUsers = Stream.concat(this.ldapUsers.stream(), Arrays.stream(ldapUsers)) - .distinct() - .sorted(Comparator.comparing(LdapUser::getUsername)) - .toList(); - } - - } - - /** - * Model for associating a role on a given project with managed users. - * - * @author Allen Shearin - * @since 5.6.0 - */ - @PersistenceCapable(table = "MANAGEDUSERS_PROJECTS_ROLES") - @Unique(name = "MANAGEDUSERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "managedUsers", "project", "role" }) - @FetchGroup(name = "ALL", members = { - @Persistent(name = "role"), - @Persistent(name = "project"), - @Persistent(name = "managedUsers") - }) - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class ManagedUserProjectRole extends ProjectRole { - - private static final long serialVersionUID = -380122087527236991L; - - /** - * Defines JDO fetch groups for this class. - */ - public enum FetchGroup { - ALL - } - - @Persistent(defaultFetchGroup = "true") - @Column(name = "MANAGEDUSER_ID", allowsNull = "false") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - private List managedUsers; - - public List getManagedUsers() { - return managedUsers; - } - - public void setManagedUsers(List managedUsers) { - this.managedUsers = managedUsers; - } - - public void addManagedUsers(ManagedUser... managedUsers) { - this.managedUsers = Objects.requireNonNullElse(this.managedUsers, new ArrayList()); - this.managedUsers = Stream.concat(this.managedUsers.stream(), Arrays.stream(managedUsers)) - .distinct() - .sorted(Comparator.comparing(ManagedUser::getUsername)) - .toList(); - } - - } - - /** - * Model for associating a role on a given project with OIDC users. - * - * @author Allen Shearin - * @since 5.6.0 - */ - @PersistenceCapable(table = "OIDCUSERS_PROJECTS_ROLES") - @Unique(name = "OIDCUSERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "oidcUsers", "project", "role" }) - @FetchGroup(name = "ALL", members = { - @Persistent(name = "role"), - @Persistent(name = "project"), - @Persistent(name = "oidcUsers") - }) - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class OidcUserProjectRole extends ProjectRole { - - private static final long serialVersionUID = -5029209056240375886L; - - /** - * Defines JDO fetch groups for this class. - */ - public enum FetchGroup { - ALL - } - - @Persistent(defaultFetchGroup = "true") - @Column(name = "OIDCUSER_ID", allowsNull = "false") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - private List oidcUsers; - - public List getOidcUsers() { - return oidcUsers; - } - - public void setOidcUsers(List oidcUsers) { - this.oidcUsers = oidcUsers; - } - - public void addOidcUsers(OidcUser... oidcUsers) { - this.oidcUsers = Objects.requireNonNullElse(this.oidcUsers, new ArrayList()); - this.oidcUsers = Stream.concat(this.oidcUsers.stream(), Arrays.stream(oidcUsers)) - .distinct() - .sorted(Comparator.comparing(OidcUser::getUsername)) - .toList(); - } - - } - } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index e8e38d8842..03ae382ecf 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -487,29 +487,8 @@ public QueryManager withL2CacheDisabled() { * @return A {@link Set} of {@link ProjectRole} IDs */ protected Set getRoleIds(final Principal principal, final Project project) { - String usersField; - Class cls; - - switch (principal) { - case LdapUser ldapUser -> { - usersField = "ldapUsers"; - cls = ProjectRole.LdapUserProjectRole.class; - } - case ManagedUser managedUser -> { - usersField = "managedUsers"; - cls = ProjectRole.ManagedUserProjectRole.class; - } - case OidcUser oidcUser -> { - usersField = "oidcUsers"; - cls = ProjectRole.OidcUserProjectRole.class; - } - default -> { - return Collections.emptySet(); - } - }; - - Query query = pm.newQuery(cls) - .filter("project.id == :projectId && %s.contains(:principal)".formatted(usersField)) + final Query query = pm.newQuery(ProjectRole.class) + .filter("project.id == :projectId && users.contains(:principal)") .setNamedParameters(Map.ofEntries( Map.entry("principal", principal), Map.entry("projectId", project.getId()))); @@ -527,8 +506,8 @@ protected Set getRoleIds(final Principal principal, final Project project) */ protected Set getTeamIds(final Principal principal) { List teams = switch (principal) { - case UserPrincipal user -> user.getTeams(); - case ApiKey apiKey -> apiKey.getTeams(); + case User user when user != null -> user.getTeams(); + case ApiKey apiKey when apiKey != null -> apiKey.getTeams(); default -> Collections.emptyList(); }; @@ -1144,15 +1123,15 @@ public synchronized RepositoryMetaComponent synchronizeRepositoryMetaComponent(f return getRepositoryQueryManager().synchronizeRepositoryMetaComponent(transientRepositoryMetaComponent); } - public boolean addRoleToUser(UserPrincipal principal, Role role, Project project){ - return getRoleQueryManager().addRoleToUser(principal, role, project); + public boolean addRoleToUser(User user, Role role, Project project){ + return getRoleQueryManager().addRoleToUser(user, role, project); } public List getUnassignedProjects(final String username) { return getRoleQueryManager().getUnassignedProjects(username); } - public List getUnassignedProjects(final UserPrincipal user) { + public List getUnassignedProjects(final User user) { return getRoleQueryManager().getUnassignedProjects(user); } @@ -1160,7 +1139,7 @@ public List getUnassignedRolePermissions(final Role role) { return getRoleQueryManager().getUnassignedRolePermissions(role); } - public List getUserRoles(final UserPrincipal user) { + public List getUserRoles(final User user) { return getRoleQueryManager().getUserRoles(user); } @@ -1168,7 +1147,7 @@ public List getUserProjectPermissions(final String username, final S return getRoleQueryManager().getUserProjectPermissions(username, projectName); } - public boolean removeRoleFromUser(final UserPrincipal user, final Role role, final Project project) { + public boolean removeRoleFromUser(final User user, final Role role, final Project project) { return getRoleQueryManager().removeRoleFromUser(user, role, project); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index e59781de08..fb891009ac 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -11,6 +11,11 @@ import org.apache.commons.lang3.StringUtils; import alpine.common.logging.Logger; +import alpine.model.LdapUser; +import alpine.model.ManagedUser; +import alpine.model.OidcUser; +import alpine.model.Permission; +import alpine.model.User; import alpine.resources.AlpineRequest; final class RoleQueryManager extends QueryManager implements IQueryManager { @@ -51,26 +56,19 @@ public Role getRole(final String uuid) { return getObjectByUuid(Role.class, uuid, Role.FetchGroup.ALL.name()); } - public Role updateRole(Role role) { - // TODO:Implement role update logic - return role; - } - - public boolean deleteRole(String uuid, boolean value) { - // TODO:Implement role deletion logic - return false; + @Override + public List getUserRoles(final User user) { + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class) + .getUserRoles(user.getUsername())); } - boolean addRoleToUser(UserPrincipal principal, Role role, String roleName, String projectName){ - //WARNING: This method is a stub. - //TODO: Implement addRoleToUser - return true; + public List getUnassignedProjects(final String username) { + return getUnassignedProjects(getUser(username)); } - boolean removeRoleFromUser(UserPrincipal principal, Role role, String roleName, String projectName){ - //WARNING: This method is a stub. - //TODO: Implement removeRoleFromUser - return true; + public List getUnassignedProjects(final User user) { + return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class) + .getUserUnassignedProjects(user.getUsername())); } public List getUnassignedRolePermissions(final Role role) { @@ -102,7 +100,7 @@ public Role updateRole(final Role transientRole) { @Override public List getUserProjectPermissions(final String username, final String projectName) { - final UserPrincipal user = getUserPrincipal(username); + final User user = getUser(username); final String columnName; switch (user) { @@ -151,19 +149,17 @@ public List getUserProjectPermissions(final String username, final S } @Override - public boolean addRoleToUser(final UserPrincipal user, final Role role, final Project project) { + public boolean addRoleToUser(final User user, final Role role, final Project project) { return JdbiFactory.withJdbiHandle( handle -> handle.attach(RoleDao.class).addRoleToUser( - user.getClass(), user.getId(), project.getId(), role.getId())) == 1; } @Override - public boolean removeRoleFromUser(final UserPrincipal user, final Role role, final Project project) { + public boolean removeRoleFromUser(final User user, final Role role, final Project project) { return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser( - user.getClass(), user.getId(), project.getName(), role.getId())) > 0; diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java index 0a99b80359..24237aef9e 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -19,6 +19,7 @@ package org.dependencytrack.persistence.jdbi; import org.jdbi.v3.sqlobject.customizer.Bind; +import org.jdbi.v3.sqlobject.statement.SqlQuery; import org.jdbi.v3.sqlobject.statement.SqlUpdate; /** @@ -40,37 +41,73 @@ public interface RoleDao { (:roleId, :permissionId) ON CONFLICT DO NOTHING """) - @DefineNamedBindings - int addPermissionToRole( - @Bind long roleId, - @Bind long permissionId); + int addPermissionToRole(@Bind long roleId, @Bind long permissionId); @SqlUpdate(/* language=sql */ """ - <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = userClass.getSimpleName()?upper_case> - INSERT INTO "${prefix}S_PROJECTS_ROLES" - ("${prefix}_ID", "PROJECT_ID", "ROLE_ID") + INSERT INTO "USERS_PROJECTS_ROLES" + ("USER_ID", "PROJECT_ID", "ROLE_ID") VALUES (:userId, :projectId, :roleId) ON CONFLICT DO NOTHING """) - @DefineNamedBindings - int addRoleToUser( - @Define Class userClass, - @Bind long userId, - @Bind long projectId, - @Bind long roleId); + int addRoleToUser(@Bind long userId, @Bind long projectId, @Bind long roleId); @SqlUpdate(/* language=sql */ """ DELETE - FROM "OIDCUSERS_PROJECTS_ROLES" - WHERE "OIDCUSER_ID" = :userId - AND "PROJECT_ACCESS_ROLE_ID" IN ( - SELECT "ID" - FROM "PROJECT_ACCESS_ROLES" - WHERE "ROLE_ID" = :roleId - AND "PROJECT_ID" = :projectId) + FROM "USERS_PROJECTS_ROLES" + WHERE "USER_ID" = :userId + AND "ROLE_ID" = :roleId + AND "PROJECT_ID" IN ( + SELECT "ID" + FROM "PROJECT" + WHERE "NAME" = :projectName + ) """) - int removeRoleFromOidcUser(@Bind final long userId, @Bind final long projectId, @Bind final long roleId); + int removeRoleFromUser(@Bind long userId, @Bind String projectName, @Bind long roleId); + + @SqlQuery(/* language=sql */ """ + SELECT + p."ID" AS "PROJECT_ID", + p."NAME" AS "PROJECT_NAME", + p."UUID" AS "PROJECT_UUID", + r."ID" AS "ROLE_ID", + r."NAME" AS "ROLE_NAME", + r."UUID" AS "ROLE_UUID", + u."ID" AS "USER_ID", + u."USERNAME" AS "USER_NAME", + u."TYPE" AS "USER_TYPE" + FROM "PROJECT" p + INNER JOIN "USERS_PROJECTS_ROLES" pr + ON pr."PROJECT_ID" = p."ID" + INNER JOIN "USER" u + ON u."ID" = pr."USER_ID" + INNER JOIN "ROLE" r + ON r."ID" = pr."ROLE_ID" + WHERE u."USERNAME" = :username + """) + @RegisterRowMapper(ProjectRoleRowMapper.class) + List getUserRoles(@Bind String username); + + @SqlQuery(/* language=sql */ """ + SELECT p."ID", p."NAME", p."UUID" + FROM "PROJECT" p + LEFT JOIN "USERS_PROJECTS_ROLES" pr + ON pr."PROJECT_ID" = p."ID" + LEFT JOIN "USER" u + ON u."ID" = pr."USER_ID" + WHERE u."USERNAME" != :username + OR u."USERNAME" IS NULL + """) + @RegisterFieldMapper(Project.class) + List getUserUnassignedProjects(@Bind String username); + + @SqlUpdate(/* language=sql */ """ + INSERT INTO "USERS_PROJECTS_ROLES" + ("USER_ID", "PROJECT_ID", "ROLE_ID") + VALUES (:userId, (SELECT "ID" FROM "PROJECT" WHERE "NAME" = :projectName), :roleId) + ON CONFLICT ("USER_ID", "PROJECT_ID") DO + UPDATE SET "ROLE_ID" = EXCLUDED."ROLE_ID" + """) + int setUserProjectRole(@Bind long userId, @Bind String projectName, @Bind long roleId); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java index e34bab48ff..f784e1ad8e 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java @@ -18,11 +18,13 @@ */ package org.dependencytrack.persistence.jdbi.mapping; +import alpine.model.LdapUser; +import alpine.model.ManagedUser; +import alpine.model.OidcUser; +import alpine.model.User; + import org.dependencytrack.model.Project; import org.dependencytrack.model.ProjectRole; -import org.dependencytrack.model.ProjectRole.LdapUserProjectRole; -import org.dependencytrack.model.ProjectRole.ManagedUserProjectRole; -import org.dependencytrack.model.ProjectRole.OidcUserProjectRole; import org.dependencytrack.model.Role; import org.jdbi.v3.core.mapper.RowMapper; @@ -30,27 +32,34 @@ import java.sql.ResultSet; import java.sql.SQLException; -import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.hasColumn; import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.maybeSet; public class ProjectRoleRowMapper implements RowMapper { public ProjectRole map(final ResultSet resultSet, final StatementContext ctx) throws SQLException { - final ProjectRole projectRole; + final ProjectRole projectRole = new ProjectRole(); + projectRole.setProject(new Project()); + projectRole.setRole(new Role()); + + final String type = resultSet.getString("USER_TYPE"); + final User user = switch (type) { + case "LDAP" -> new LdapUser(); + case "MANAGED" -> new ManagedUser(); + case "OIDC" -> new OidcUser(); + default -> null; + }; + + if (user == null) + return projectRole; - switch (resultSet) { - case ResultSet rs when hasColumn(rs, "LDAPUSER_ID") -> projectRole = new LdapUserProjectRole(); - case ResultSet rs when hasColumn(rs, "MANAGEDUSER_ID") -> projectRole = new ManagedUserProjectRole(); - case ResultSet rs when hasColumn(rs, "OIDCUSER_ID") -> projectRole = new OidcUserProjectRole(); - default -> { - return null; - } - } + maybeSet(resultSet, "USER_ID", ResultSet::getLong, user::setId); + maybeSet(resultSet, "USER_NAME", ResultSet::getString, user::setUsername); + projectRole.addUsers(user); - maybeSet(resultSet, "PROJECT_ID", ResultSet::getLong, value -> { - var project = new Project(); - project.setId(value); - projectRole.setProject(project); + maybeSet(resultSet, "PROJECT_ID", ResultSet::getLong, projectRole.getProject()::setId); + maybeSet(resultSet, "PROJECT_NAME", ResultSet::getString, projectRole.getProject()::setName); + maybeSet(resultSet, "PROJECT_UUID", ResultSet::getString, value -> { + projectRole.getProject().setUuid(UUID.fromString(value)); }); maybeSet(resultSet, "ROLE_ID", ResultSet::getLong, value -> { diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index b319dd9ef8..3319b31f9a 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -144,11 +144,11 @@ public Response retrieveUserProjects( try (final Handle jdbiHandle = openJdbiHandle()) { var dao = jdbiHandle.attach(RoleDao.class); - List projects = dao.getUserUnassignedProjects(principal.getClass(), principal.getUsername()); + List projects = dao.getUserUnassignedProjects(user.getUsername()); if (projects == null || projects.isEmpty()) - return Response.status(Response.Status.NOT_FOUND).entity("No unassigned projects for specified user.").build(); - + return Response.noContent().build(); + return Response.ok(projects).header(TOTAL_COUNT_HEADER, projects.size()).build(); } } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index 40c19a26f8..80736b1524 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -58,7 +58,7 @@ import org.owasp.security.logging.SecurityMarkers; import alpine.model.Permission; -import alpine.model.UserPrincipal; +import alpine.model.User; import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; @@ -236,8 +236,31 @@ public Response deleteRole(Role jsonRole) { } } + @GET + @Path("/{username}/roles") + @Produces(MediaType.APPLICATION_JSON) + @Operation( + summary = "Returns a list of roles assigned to the specified user", + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

") + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "A list of roles assigned to the user", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProjectRole.class)))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The user could not be found") + }) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ }) + public Response getUserRoles( + @Parameter(description = "A valid username", required = true) @PathParam("username") String username) { + try (QueryManager qm = new QueryManager()) { + User user = qm.getUser(username); + if (user == null) { + LOGGER.warn("User not found: " + username); + return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); + } - List roles = qm.getUserRoles(principal); + List roles = qm.getUserRoles(user); if (roles == null || roles.isEmpty()) { LOGGER.info("No roles found for user: " + username); return Response.ok(List.of()).build(); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index c0ece5e810..abc22709ae 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -18,23 +18,6 @@ */ package org.dependencytrack.resources.v1; -import java.security.Principal; -import java.util.List; -import java.util.Optional; - -import org.apache.commons.lang3.StringUtils; -import org.dependencytrack.auth.Permissions; -import org.dependencytrack.event.kafka.KafkaEventDispatcher; -import org.dependencytrack.model.IdentifiableObject; -import org.dependencytrack.model.Project; -import org.dependencytrack.model.Role; -import org.dependencytrack.notification.NotificationConstants; -import org.dependencytrack.notification.NotificationGroup; -import org.dependencytrack.notification.NotificationScope; -import org.dependencytrack.persistence.QueryManager; -import org.dependencytrack.proto.notification.v1.UserSubject; -import org.owasp.security.logging.SecurityMarkers; - import alpine.Config; import alpine.common.logging.Logger; import alpine.model.LdapUser; @@ -89,9 +72,20 @@ import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import javax.jdo.Query; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; /** * JAX-RS resources for processing users. @@ -868,7 +862,7 @@ private UserSubject buildUserSubject(final String username, final String email) @ApiResponse( responseCode = "200", description = "Updated user with a specific role", - content = @Content(schema = @Schema(implementation = UserPrincipal.class)) + content = @Content(schema = @Schema(implementation = User.class)) ), @ApiResponse(responseCode = "304", description = "The user has already been assigned to this role."), @ApiResponse(responseCode = "401", description = "Unauthorized"), @@ -895,24 +889,24 @@ public Response addRoleToUser( if (role == null) return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); - UserPrincipal principal = qm.getUserPrincipal(username); - if (principal == null) + User user = qm.getUser(username); + if (user == null) return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); Project project = qm.getProject(projectName, projectVersion); if (project == null) return Response.status(Response.Status.NOT_FOUND).entity("The project could not be found.").build(); - final boolean modified = qm.addRoleToUser(principal, role, project); + final boolean modified = qm.addRoleToUser(user, role, project); if (!modified) return Response.notModified().entity("The user is already a member of the specified role.").build(); principal = qm.getObjectById(principal.getClass(), principal.getId()); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added role membership for: %s / role: %s / project: %s" - .formatted(principal.getName(), role.getName(), projectName)); + .formatted(user.getName(), role.getName(), project.getName())); - return Response.ok(principal).build(); + return Response.ok(user).build(); } } @@ -928,8 +922,7 @@ public Response addRoleToUser( @ApiResponse( responseCode = "200", description = "Updated user with a specific role removed", - content = @Content(schema = @Schema(implementation = UserPrincipal.class)) - ), + content = @Content(schema = @Schema(implementation = User.class))), @ApiResponse(responseCode = "204", description = "The role has been successfully removed from the user"), @ApiResponse(responseCode = "304", description = "The user is not a member of the specified role"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @@ -956,25 +949,84 @@ public Response removeRoleFromUser( if (role == null) return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); - UserPrincipal principal = qm.getUserPrincipal(username); - if (principal == null) + User user = qm.getUser(username); + if (user == null) return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); Project project = qm.getProject(projectName, projectVersion); if (project == null) return Response.status(Response.Status.NOT_FOUND).entity("The project could not be found.").build(); - final boolean modified = qm.removeRoleFromUser(principal, role, project); + final boolean modified = qm.removeRoleFromUser(user, role, project); if (!modified) return Response.notModified().entity("The user is not a member of the specified role.").build(); - principal = qm.getObjectById(principal.getClass(), principal.getId()); + user = qm.getObjectById(user.getClass(), user.getId()); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Removed role membership for: %s / role: %s / project: %s" - .formatted(principal.getName(), role.getName(), projectName)); + .formatted(user.getName(), role.getName(), project.getName())); return Response.noContent().build(); } } + @PUT + @Path("/{username}/membership") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(summary = "Adds the username to the specified team.", description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "The updated user", content = @Content(schema = @Schema(implementation = User.class))), + @ApiResponse(responseCode = "304", description = "The user is already a member of the specified team(s)"), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The user or team(s) could not be found") + }) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) + public Response setUserTeams( + @Parameter(description = "A valid username", required = true) @PathParam("username") String username, + @Parameter(description = "The UUID(s) of the team(s) to associate username with", required = true) @Valid TeamsSetRequest request) { + try (QueryManager qm = new QueryManager()) { + User user = qm.getUser(username); + if (user == null) { + return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); + } + + // Compare given team uuids against current user teams + final Set currentUserTeams = user.getTeams() == null ? Collections.emptySet() + : user.getTeams().stream() + .map(Team::getUuid) + .map(UUID::toString) + .collect(Collectors.toSet()); + + if (currentUserTeams.equals(request.teams())) { + return Response.notModified().entity("The user is already a member of the selected team(s)").build(); + } + + List requestedTeams = request.teams() + .stream() + .map(uuid -> qm.getObjectByUuid(Team.class, uuid)) + .toList(); + + // check that all requested teams exist + List notFound = new ArrayList<>(); + for (int i = 0; i < requestedTeams.size(); i++) { + if (requestedTeams.get(i) == null) + notFound.add(request.teams().stream().toList().get(i)); + } + + if (notFound.size() > 0) { + // String msg = String.format("One or more teams could not be found:\n%s", ); + Map response = new HashMap<>(); + response.put("error", "One or more teams could not be found"); + response.put("teams", notFound); + return Response.status(Response.Status.BAD_REQUEST).entity(response).build(); + } + + user.setTeams(requestedTeams); + qm.persist(user); + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, + "Added team membership for: " + user.getName() + " / team: " + requestedTeams.toString()); + return Response.ok(user).build(); + } + } } diff --git a/apiserver/src/main/resources/META-INF/persistence.xml b/apiserver/src/main/resources/META-INF/persistence.xml index 3a8d34ac99..f4a1923af4 100644 --- a/apiserver/src/main/resources/META-INF/persistence.xml +++ b/apiserver/src/main/resources/META-INF/persistence.xml @@ -53,9 +53,7 @@ org.dependencytrack.model.Project org.dependencytrack.model.ProjectMetadata org.dependencytrack.model.ProjectProperty - org.dependencytrack.model.ProjectRole$LdapUserProjectRole - org.dependencytrack.model.ProjectRole$ManagedUserProjectRole - org.dependencytrack.model.ProjectRole$OidcUserProjectRole + org.dependencytrack.model.ProjectRole org.dependencytrack.model.Repository org.dependencytrack.model.RepositoryMetaComponent org.dependencytrack.model.ServiceComponent diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 142269eb8e..9e1f24bea1 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -38,7 +38,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.UUID; import org.dependencytrack.PersistenceCapableTest; import org.junit.After; @@ -53,7 +52,6 @@ public class RoleQueryManagerTest extends PersistenceCapableTest { private PostgreSQLContainer postgresContainer; - private Jdbi jdbi; @Before public void setUp() { @@ -63,7 +61,7 @@ public void setUp() { postgresContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:11-alpine")); postgresContainer.start(); - jdbi = Jdbi.create( + Jdbi.create( postgresContainer.getJdbcUrl(), postgresContainer.getUsername(), postgresContainer.getPassword()); @@ -166,12 +164,11 @@ public void testGetUserRoles() throws ParseException { JdbiFactory.withJdbiHandle( handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getClass(), testUser.getId(), testProject.getId(), expectedRole.getId())); - List actualRoles = qm.getUserRoles(testUser); + List actualRoles = qm.getUserRoles(testUser); Assert.assertEquals(actualRoles.size(), 1); Assert.assertEquals(expectedRole.toString(), actualRoles.get(0).getRole().toString()); @@ -213,7 +210,6 @@ public void testGetUnassignedProjects() throws ParseException { JdbiFactory.withJdbiHandle( handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getClass(), testUser.getId(), assignedProject.getId(), maintainerRole.getId())); @@ -347,7 +343,6 @@ public void testGetUserProjectPermissions() throws ParseException { JdbiFactory.withJdbiHandle( handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getClass(), testUser.getId(), testProject.getId(), maintainerRole.getId())); @@ -411,11 +406,11 @@ public void testRemoveRoleFromUser() throws ParseException { JdbiFactory.withJdbiHandle( handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getClass(), testUser.getId(), testProject.getId(), maintainerRole.getId())); Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); } + } diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java index 3136116c4e..255b597c09 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java @@ -502,8 +502,7 @@ public void addTeamToRuleWithCustomEmailPublisherTest() { "teams": [ { "uuid": "${json-unit.matches:teamUuid}", - "name": "Team Example", - "permissions": [] + "name": "Team Example" } ], "notifyOn": [], diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java index 9677001edb..bc8c2960cd 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java @@ -253,7 +253,7 @@ public void removePermissionFromTeamTest() { JsonObject json = parseJsonObject(response); Assert.assertNotNull(json); Assert.assertEquals("team1", json.getString("name")); - Assert.assertEquals(0, json.getJsonArray("permissions").size()); + Assert.assertFalse(json.containsKey("permissions")); } @Test diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java index ccc9e220ba..e69d9bef78 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -107,7 +107,7 @@ public void getRoleByInvalidUuidTest() { @Test public void createRoleTest() { - initializeWithPermissions(Permissions.ROLE_MANAGEMENT_CREATE); + initializeWithPermissions(Permissions.ACCESS_MANAGEMENT_CREATE); Response response = jersey.target(V1_ROLE).request() .header(X_API_KEY, apiKey) @@ -174,7 +174,6 @@ public void getUserRolesTest() throws ParseException { JdbiFactory.withJdbiHandle( handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getClass(), testUser.getId(), testProject.getId(), expectedRole.getId())); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java index 9caf04ed61..a633977105 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java @@ -156,7 +156,7 @@ public void createTeamTest() { Assert.assertNotNull(json); Assert.assertEquals("My Team", json.getString("name")); Assert.assertTrue(UuidUtil.isValidUUID(json.getString("uuid"))); - Assert.assertEquals(0, json.getJsonArray("apiKeys").size()); + Assert.assertFalse(json.containsKey("apiKeys")); } @Test diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index 100558cfcb..81ffdc80de 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -1942,401 +1942,4 @@ EXECUTE FUNCTION prevent_direct_effective_permissions_writes();
- - - - - = %L AND "LAST_OCCURRENCE" < %L;', - target_table, - columns, - columns, - source_table, - partition_date, - next_day - ); - - partition_date := next_day; - END LOOP; - END; - $$; - ]]> - - - - CREATE TABLE "PORTFOLIOMETRICS_NEW" - ( - "COMPONENTS" int4 NOT NULL, - "CRITICAL" int4 NOT NULL, - "FINDINGS_AUDITED" int4 NULL, - "FINDINGS_TOTAL" int4 NULL, - "FINDINGS_UNAUDITED" int4 NULL, - "FIRST_OCCURRENCE" timestamptz NOT NULL, - "HIGH" int4 NOT NULL, - "RISKSCORE" float8 NOT NULL, - "LAST_OCCURRENCE" timestamptz NOT NULL, - "LOW" int4 NOT NULL, - "MEDIUM" int4 NOT NULL, - "POLICYVIOLATIONS_AUDITED" int4 NULL, - "POLICYVIOLATIONS_FAIL" int4 NULL, - "POLICYVIOLATIONS_INFO" int4 NULL, - "POLICYVIOLATIONS_LICENSE_AUDITED" int4 NULL, - "POLICYVIOLATIONS_LICENSE_TOTAL" int4 NULL, - "POLICYVIOLATIONS_LICENSE_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_AUDITED" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_TOTAL" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_SECURITY_AUDITED" int4 NULL, - "POLICYVIOLATIONS_SECURITY_TOTAL" int4 NULL, - "POLICYVIOLATIONS_SECURITY_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_TOTAL" int4 NULL, - "POLICYVIOLATIONS_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_WARN" int4 NULL, - "PROJECTS" int4 NOT NULL, - "SUPPRESSED" int4 NOT NULL, - "UNASSIGNED_SEVERITY" int4 NULL, - "VULNERABILITIES" int4 NOT NULL, - "VULNERABLECOMPONENTS" int4 NOT NULL, - "VULNERABLEPROJECTS" int4 NOT NULL, - CONSTRAINT "PORTFOLIOMETRICS_NEW_PK" PRIMARY KEY ("LAST_OCCURRENCE") - ) PARTITION BY RANGE ("LAST_OCCURRENCE"); - - - - CREATE TABLE "PROJECTMETRICS_NEW" - ( - "COMPONENTS" int4 NOT NULL, - "CRITICAL" int4 NOT NULL, - "FINDINGS_AUDITED" int4 NULL, - "FINDINGS_TOTAL" int4 NULL, - "FINDINGS_UNAUDITED" int4 NULL, - "FIRST_OCCURRENCE" timestamptz NOT NULL, - "HIGH" int4 NOT NULL, - "RISKSCORE" float8 NOT NULL, - "LAST_OCCURRENCE" timestamptz NOT NULL, - "LOW" int4 NOT NULL, - "MEDIUM" int4 NOT NULL, - "POLICYVIOLATIONS_AUDITED" int4 NULL, - "POLICYVIOLATIONS_FAIL" int4 NULL, - "POLICYVIOLATIONS_INFO" int4 NULL, - "POLICYVIOLATIONS_LICENSE_AUDITED" int4 NULL, - "POLICYVIOLATIONS_LICENSE_TOTAL" int4 NULL, - "POLICYVIOLATIONS_LICENSE_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_AUDITED" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_TOTAL" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_SECURITY_AUDITED" int4 NULL, - "POLICYVIOLATIONS_SECURITY_TOTAL" int4 NULL, - "POLICYVIOLATIONS_SECURITY_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_TOTAL" int4 NULL, - "POLICYVIOLATIONS_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_WARN" int4 NULL, - "PROJECT_ID" int8 NOT NULL, - "SUPPRESSED" int4 NOT NULL, - "UNASSIGNED_SEVERITY" int4 NULL, - "VULNERABILITIES" int4 NOT NULL, - "VULNERABLECOMPONENTS" int4 NOT NULL, - CONSTRAINT "PROJECTMETRICS_NEW_PK" PRIMARY KEY ("PROJECT_ID", "LAST_OCCURRENCE") - ) PARTITION BY RANGE ("LAST_OCCURRENCE"); - - - - CREATE TABLE "DEPENDENCYMETRICS_NEW" - ( - "COMPONENT_ID" int8 NOT NULL, - "CRITICAL" int4 NOT NULL, - "FINDINGS_AUDITED" int4 NULL, - "FINDINGS_TOTAL" int4 NULL, - "FINDINGS_UNAUDITED" int4 NULL, - "FIRST_OCCURRENCE" timestamptz NOT NULL, - "HIGH" int4 NOT NULL, - "RISKSCORE" float8 NOT NULL, - "LAST_OCCURRENCE" timestamptz NOT NULL, - "LOW" int4 NOT NULL, - "MEDIUM" int4 NOT NULL, - "POLICYVIOLATIONS_AUDITED" int4 NULL, - "POLICYVIOLATIONS_FAIL" int4 NULL, - "POLICYVIOLATIONS_INFO" int4 NULL, - "POLICYVIOLATIONS_LICENSE_AUDITED" int4 NULL, - "POLICYVIOLATIONS_LICENSE_TOTAL" int4 NULL, - "POLICYVIOLATIONS_LICENSE_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_AUDITED" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_TOTAL" int4 NULL, - "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_SECURITY_AUDITED" int4 NULL, - "POLICYVIOLATIONS_SECURITY_TOTAL" int4 NULL, - "POLICYVIOLATIONS_SECURITY_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_TOTAL" int4 NULL, - "POLICYVIOLATIONS_UNAUDITED" int4 NULL, - "POLICYVIOLATIONS_WARN" int4 NULL, - "PROJECT_ID" int8 NOT NULL, - "SUPPRESSED" int4 NOT NULL, - "UNASSIGNED_SEVERITY" int4 NULL, - "VULNERABILITIES" int4 NOT NULL, - CONSTRAINT "DEPENDENCYMETRICS_NEW_PK" PRIMARY KEY ("PROJECT_ID", "COMPONENT_ID", "LAST_OCCURRENCE") - ) PARTITION BY RANGE ("LAST_OCCURRENCE"); - - - - - - - -- call the migration procedure - CALL "MIGRATE_METRICS_TO_PARTITIONS"('PORTFOLIOMETRICS_NEW'::TEXT, 'PORTFOLIOMETRICS'::TEXT, - '"COMPONENTS", "CRITICAL", "FINDINGS_AUDITED", "FINDINGS_TOTAL", "FINDINGS_UNAUDITED", "FIRST_OCCURRENCE", "HIGH", "RISKSCORE", "LAST_OCCURRENCE", "LOW", "MEDIUM", "POLICYVIOLATIONS_AUDITED", "POLICYVIOLATIONS_FAIL", "POLICYVIOLATIONS_INFO", "POLICYVIOLATIONS_LICENSE_AUDITED", "POLICYVIOLATIONS_LICENSE_TOTAL", "POLICYVIOLATIONS_LICENSE_UNAUDITED", "POLICYVIOLATIONS_OPERATIONAL_AUDITED", "POLICYVIOLATIONS_OPERATIONAL_TOTAL", "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED", "POLICYVIOLATIONS_SECURITY_AUDITED", "POLICYVIOLATIONS_SECURITY_TOTAL", "POLICYVIOLATIONS_SECURITY_UNAUDITED", "POLICYVIOLATIONS_TOTAL", "POLICYVIOLATIONS_UNAUDITED", "POLICYVIOLATIONS_WARN", "PROJECTS", "SUPPRESSED", "UNASSIGNED_SEVERITY", "VULNERABILITIES", "VULNERABLECOMPONENTS", "VULNERABLEPROJECTS"'); - - -- drop old table - DROP TABLE "PORTFOLIOMETRICS"; - - -- rename partitioned table - ALTER TABLE "PORTFOLIOMETRICS_NEW" RENAME TO "PORTFOLIOMETRICS"; - - -- rename PK - ALTER TABLE "PORTFOLIOMETRICS" RENAME CONSTRAINT "PORTFOLIOMETRICS_NEW_PK" TO "PORTFOLIOMETRICS_PK"; - - - - - - - -- call the migration procedure - CALL "MIGRATE_METRICS_TO_PARTITIONS"('PROJECTMETRICS_NEW'::TEXT, 'PROJECTMETRICS'::TEXT, - '"COMPONENTS", "CRITICAL", "FINDINGS_AUDITED", "FINDINGS_TOTAL", "FINDINGS_UNAUDITED", "FIRST_OCCURRENCE", "HIGH", "RISKSCORE", "LAST_OCCURRENCE", "LOW", "MEDIUM", "POLICYVIOLATIONS_AUDITED", "POLICYVIOLATIONS_FAIL", "POLICYVIOLATIONS_INFO", "POLICYVIOLATIONS_LICENSE_AUDITED", "POLICYVIOLATIONS_LICENSE_TOTAL", "POLICYVIOLATIONS_LICENSE_UNAUDITED", "POLICYVIOLATIONS_OPERATIONAL_AUDITED", "POLICYVIOLATIONS_OPERATIONAL_TOTAL", "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED", "POLICYVIOLATIONS_SECURITY_AUDITED", "POLICYVIOLATIONS_SECURITY_TOTAL", "POLICYVIOLATIONS_SECURITY_UNAUDITED", "POLICYVIOLATIONS_TOTAL", "POLICYVIOLATIONS_UNAUDITED", "POLICYVIOLATIONS_WARN", "PROJECT_ID", "SUPPRESSED", "UNASSIGNED_SEVERITY", "VULNERABILITIES", "VULNERABLECOMPONENTS"'); - - -- drop old table - DROP TABLE "PROJECTMETRICS"; - - -- rename partitioned table - ALTER TABLE "PROJECTMETRICS_NEW" RENAME TO "PROJECTMETRICS"; - - -- rename PK - ALTER TABLE "PROJECTMETRICS" RENAME CONSTRAINT "PROJECTMETRICS_NEW_PK" TO "PROJECTMETRICS_PK"; - - - - - - - -- call the migration procedure - CALL "MIGRATE_METRICS_TO_PARTITIONS"('DEPENDENCYMETRICS_NEW'::TEXT, 'DEPENDENCYMETRICS'::TEXT, - '"COMPONENT_ID", "CRITICAL", "FINDINGS_AUDITED", "FINDINGS_TOTAL", "FINDINGS_UNAUDITED", "FIRST_OCCURRENCE", "HIGH", "RISKSCORE", "LAST_OCCURRENCE", "LOW", "MEDIUM", "POLICYVIOLATIONS_AUDITED", "POLICYVIOLATIONS_FAIL", "POLICYVIOLATIONS_INFO", "POLICYVIOLATIONS_LICENSE_AUDITED", "POLICYVIOLATIONS_LICENSE_TOTAL", "POLICYVIOLATIONS_LICENSE_UNAUDITED", "POLICYVIOLATIONS_OPERATIONAL_AUDITED", "POLICYVIOLATIONS_OPERATIONAL_TOTAL", "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED", "POLICYVIOLATIONS_SECURITY_AUDITED", "POLICYVIOLATIONS_SECURITY_TOTAL", "POLICYVIOLATIONS_SECURITY_UNAUDITED", "POLICYVIOLATIONS_TOTAL", "POLICYVIOLATIONS_UNAUDITED", "POLICYVIOLATIONS_WARN", "PROJECT_ID", "SUPPRESSED", "UNASSIGNED_SEVERITY", "VULNERABILITIES"'); - - -- drop old table - DROP TABLE "DEPENDENCYMETRICS"; - - -- rename partitioned table - ALTER TABLE "DEPENDENCYMETRICS_NEW" RENAME TO "DEPENDENCYMETRICS"; - - -- rename PK - ALTER TABLE "DEPENDENCYMETRICS" RENAME CONSTRAINT "DEPENDENCYMETRICS_NEW_PK" TO "DEPENDENCYMETRICS_PK"; - - - - - - - - - - - - - - - - SET CONSTRAINTS ALL IMMEDIATE - - - - - - - - - - DROP INDEX IF EXISTS "TAG_NAME_IDX" - - - - CREATE TEMPORARY TABLE tmp_duplicate_tag - ON COMMIT DROP - AS - SELECT "NAME" AS name - , MIN("ID") AS canonical_id - FROM "TAG" - GROUP BY "NAME" - HAVING COUNT(*) > 1; - - - - - CREATE FUNCTION cleanup_duplicate_tag_relationships( - table_name TEXT, - relation_id_column TEXT - ) - RETURNS void AS $$ - BEGIN - EXECUTE format($q$ - UPDATE %1$I AS tag_relationship - SET "TAG_ID" = tmp_duplicate_tag.canonical_id - FROM tmp_duplicate_tag - INNER JOIN "TAG" - ON "TAG"."NAME" = tmp_duplicate_tag.name - AND "TAG"."ID" != tmp_duplicate_tag.canonical_id - WHERE tag_relationship."TAG_ID" = "TAG"."ID"; - $q$, table_name, relation_id_column - ); - - EXECUTE format($q$ - WITH cte_dupe AS ( - SELECT "TAG_ID" - , %2$I - FROM %1$I AS tag_relationship - GROUP BY "TAG_ID" - , %2$I - HAVING COUNT(*) > 1 - ), - cte_deleted_dupe AS ( - DELETE FROM %1$I AS tag_relationship - USING cte_dupe - WHERE tag_relationship."TAG_ID" = cte_dupe."TAG_ID" - AND tag_relationship.%2$I = cte_dupe.%2$I - RETURNING tag_relationship."TAG_ID" - , tag_relationship.%2$I - ) - INSERT INTO %1$I ("TAG_ID", %2$I) - SELECT DISTINCT "TAG_ID", %2$I FROM cte_deleted_dupe; - $q$, table_name, relation_id_column - ); - END; - $$ LANGUAGE plpgsql; - - - - DO $$ - BEGIN - PERFORM cleanup_duplicate_tag_relationships('NOTIFICATIONRULE_TAGS', 'NOTIFICATIONRULE_ID'); - PERFORM cleanup_duplicate_tag_relationships('POLICY_TAGS', 'POLICY_ID'); - PERFORM cleanup_duplicate_tag_relationships('PROJECTS_TAGS', 'PROJECT_ID'); - PERFORM cleanup_duplicate_tag_relationships('VULNERABILITIES_TAGS', 'VULNERABILITY_ID'); - END - $$; - - - - DROP FUNCTION cleanup_duplicate_tag_relationships; - - DELETE FROM "TAG" - USING tmp_duplicate_tag - WHERE "TAG"."NAME" = tmp_duplicate_tag.name - AND "TAG"."ID" != tmp_duplicate_tag.canonical_id; - - - - - - - - - - - diff --git a/src/main/resources/migration/changelog-v5.6.0-roles.xml b/src/main/resources/migration/changelog-v5.6.0-roles.xml index fa21c426c8..85ede4a7c8 100644 --- a/src/main/resources/migration/changelog-v5.6.0-roles.xml +++ b/src/main/resources/migration/changelog-v5.6.0-roles.xml @@ -66,135 +66,38 @@ - - - + + + validateForeignKey="true" /> - + validateForeignKey="true" /> - + validateForeignKey="true" /> - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -210,25 +113,16 @@ DELETE FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" WHERE "PROJECT_ID" = ANY(project_ids); - -- Rebuild effective permissions for all user types - FOREACH tbl_prefix IN ARRAY ARRAY['LDAP', 'MANAGED', 'OIDC'] - LOOP - EXECUTE format($query$ - INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" - (%I, "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") - SELECT DISTINCT upr.%I, upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" - FROM %I upr - INNER JOIN "ROLES_PERMISSIONS" rp - ON rp."ROLE_ID" = upr."ROLE_ID" - INNER JOIN "PERMISSION" p - ON p."ID" = rp."PERMISSION_ID" - WHERE upr."PROJECT_ID" = ANY($1); - $query$, - tbl_prefix || 'USER_ID', - tbl_prefix || 'USER_ID', - tbl_prefix || 'USERS_PROJECTS_ROLES') - USING project_ids; - END LOOP; + -- Rebuild effective permissions for all users + INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" + ("USER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") + SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" + FROM "USERS_PROJECTS_ROLES" upr + INNER JOIN "ROLES_PERMISSIONS" rp + ON rp."ROLE_ID" = upr."ROLE_ID" + INNER JOIN "PERMISSION" p + ON p."ID" = rp."PERMISSION_ID" + WHERE upr."PROJECT_ID" = ANY(project_ids); END; $$ LANGUAGE plpgsql; @@ -248,29 +142,16 @@ SELECT ARRAY_AGG(sub."PROJECT_ID") INTO project_ids FROM ( - SELECT lpr."PROJECT_ID" - FROM "LDAPUSERS_PROJECTS_ROLES" lpr + SELECT upr."PROJECT_ID" + FROM "USERS_PROJECTS_ROLES" upr INNER JOIN old_table - ON old_table."ROLE_ID" = lpr."ROLE_ID" - UNION - SELECT mpr."PROJECT_ID" - FROM "MANAGEDUSERS_PROJECTS_ROLES" mpr - INNER JOIN old_table - ON old_table."ROLE_ID" = mpr."ROLE_ID" - UNION - SELECT opr."PROJECT_ID" - FROM "OIDCUSERS_PROJECTS_ROLES" opr - INNER JOIN old_table - ON old_table."ROLE_ID" = opr."ROLE_ID" + ON old_table."ROLE_ID" = upr."ROLE_ID" ) sub; ELSE - EXECUTE format($query$ - SELECT ARRAY_AGG(DISTINCT t."PROJECT_ID") - FROM %I AS t - WHERE t."ROLE_ID" = ANY($1) - $query$, TG_TABLE_NAME) - USING role_ids - INTO project_ids; + SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") + INTO project_ids + FROM "USERS_PROJECTS_ROLES" + WHERE "ROLE_ID" = ANY(role_ids); END IF; PERFORM recalc_user_project_role_effective_permissions(project_ids); @@ -294,29 +175,16 @@ SELECT ARRAY_AGG(sub."PROJECT_ID") INTO project_ids FROM ( - SELECT lpr."PROJECT_ID" - FROM "LDAPUSERS_PROJECTS_ROLES" lpr + SELECT upr."PROJECT_ID" + FROM "USERS_PROJECTS_ROLES" upr INNER JOIN new_table - ON new_table."ROLE_ID" = lpr."ROLE_ID" - UNION - SELECT mpr."PROJECT_ID" - FROM "MANAGEDUSERS_PROJECTS_ROLES" mpr - INNER JOIN new_table - ON new_table."ROLE_ID" = mpr."ROLE_ID" - UNION - SELECT opr."PROJECT_ID" - FROM "OIDCUSERS_PROJECTS_ROLES" opr - INNER JOIN new_table - ON new_table."ROLE_ID" = opr."ROLE_ID" + ON new_table."ROLE_ID" = upr."ROLE_ID" ) sub; ELSE - EXECUTE format($query$ - SELECT ARRAY_AGG(DISTINCT t."PROJECT_ID") - FROM %I AS t - WHERE t."ROLE_ID" = ANY($1) - $query$, TG_TABLE_NAME) - USING role_ids - INTO project_ids; + SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") + INTO project_ids + FROM "USERS_PROJECTS_ROLES" + WHERE "ROLE_ID" = ANY(role_ids); END IF; PERFORM recalc_user_project_role_effective_permissions(project_ids); @@ -344,35 +212,18 @@ SELECT ARRAY_AGG(sub."PROJECT_ID") INTO project_ids FROM ( - SELECT lpr."PROJECT_ID" - FROM "LDAPUSERS_PROJECTS_ROLES" lpr - INNER JOIN new_table - ON new_table."ROLE_ID" = lpr."ROLE_ID" - FULL OUTER JOIN old_table - ON new_table."ROLE_ID" = old_table."ROLE_ID" - UNION - SELECT mpr."PROJECT_ID" - FROM "MANAGEDUSERS_PROJECTS_ROLES" mpr - INNER JOIN new_table - ON new_table."ROLE_ID" = mpr."ROLE_ID" - FULL OUTER JOIN old_table - ON new_table."ROLE_ID" = old_table."ROLE_ID" - UNION - SELECT opr."PROJECT_ID" - FROM "OIDCUSERS_PROJECTS_ROLES" opr + SELECT upr."PROJECT_ID" + FROM "USERS_PROJECTS_ROLES" upr INNER JOIN new_table - ON new_table."ROLE_ID" = opr."ROLE_ID" + ON new_table."ROLE_ID" = upr."ROLE_ID" FULL OUTER JOIN old_table ON new_table."ROLE_ID" = old_table."ROLE_ID" ) sub; ELSE - EXECUTE format($query$ - SELECT ARRAY_AGG(DISTINCT t."PROJECT_ID") - FROM %I AS t - WHERE t."ROLE_ID" = ANY($1) - $query$, TG_TABLE_NAME) - USING role_ids - INTO project_ids; + SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") + INTO project_ids + FROM "USERS_PROJECTS_ROLES" + WHERE "ROLE_ID" = ANY(role_ids); END IF; PERFORM recalc_user_project_role_effective_permissions(project_ids); @@ -382,65 +233,23 @@ - -- INSERT trigger for LDAPUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_roles_insert - AFTER INSERT ON "LDAPUSERS_PROJECTS_ROLES" - REFERENCING NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); - - -- DELETE trigger for LDAPUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_roles_delete - AFTER DELETE ON "LDAPUSERS_PROJECTS_ROLES" - REFERENCING OLD TABLE AS old_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); - - -- UPDATE trigger for LDAPUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_ldapusers_roles_update - AFTER UPDATE ON "LDAPUSERS_PROJECTS_ROLES" - REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_update(); - - -- INSERT trigger for MANAGEDUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_mgdusers_roles_insert - AFTER INSERT ON "MANAGEDUSERS_PROJECTS_ROLES" - REFERENCING NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); - - -- DELETE trigger for MANAGEDUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_mgdusers_roles_delete - AFTER DELETE ON "MANAGEDUSERS_PROJECTS_ROLES" - REFERENCING OLD TABLE AS old_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); - - -- UPDATE trigger for MANAGEDUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_mgdusers_roles_update - AFTER UPDATE ON "MANAGEDUSERS_PROJECTS_ROLES" - REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_update(); - - -- INSERT trigger for OIDCUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_roles_insert - AFTER INSERT ON "OIDCUSERS_PROJECTS_ROLES" + -- INSERT trigger for USERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_insert + AFTER INSERT ON "USERS_PROJECTS_ROLES" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); - -- DELETE trigger for OIDCUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_roles_delete - AFTER DELETE ON "OIDCUSERS_PROJECTS_ROLES" + -- DELETE trigger for USERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_delete + AFTER DELETE ON "USERS_PROJECTS_ROLES" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); - -- UPDATE trigger for OIDCUSERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_oidcusers_roles_update - AFTER UPDATE ON "OIDCUSERS_PROJECTS_ROLES" + -- UPDATE trigger for USERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_update + AFTER UPDATE ON "USERS_PROJECTS_ROLES" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_update(); From d1cca652d90da1f9becb996ee07253433b08e28f Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Wed, 14 May 2025 16:32:07 -0500 Subject: [PATCH 22/45] fix: cascade delete user foreign key (#24) Signed-off-by: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> --- src/main/resources/migration/changelog-v5.6.0-roles.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/migration/changelog-v5.6.0-roles.xml b/src/main/resources/migration/changelog-v5.6.0-roles.xml index 85ede4a7c8..8e69187b15 100644 --- a/src/main/resources/migration/changelog-v5.6.0-roles.xml +++ b/src/main/resources/migration/changelog-v5.6.0-roles.xml @@ -71,7 +71,7 @@ From 5b7728435bea827e67ebc7409519045b9d94ba04 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Wed, 21 May 2025 12:13:59 -0600 Subject: [PATCH 23/45] Regenerate jooq with role tables Signed-off-by: Allen Shearin --- .../main/resources/META-INF/persistence.xml | 1 - .../resources/migration/changelog-v5.6.0.xml | 655 ++++++++++++++++++ .../migration/changelog-v5.6.0-roles.xml | 279 -------- 3 files changed, 655 insertions(+), 280 deletions(-) delete mode 100644 src/main/resources/migration/changelog-v5.6.0-roles.xml diff --git a/apiserver/src/main/resources/META-INF/persistence.xml b/apiserver/src/main/resources/META-INF/persistence.xml index f4a1923af4..0a77577e77 100644 --- a/apiserver/src/main/resources/META-INF/persistence.xml +++ b/apiserver/src/main/resources/META-INF/persistence.xml @@ -40,7 +40,6 @@ org.dependencytrack.model.Component org.dependencytrack.model.ComponentOccurrence org.dependencytrack.model.ComponentProperty - org.dependencytrack.model.DependencyMetrics org.dependencytrack.model.Epss org.dependencytrack.model.FindingAttribution org.dependencytrack.model.License diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index 81ffdc80de..e9ec54a4fd 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -1942,4 +1942,659 @@ EXECUTE FUNCTION prevent_direct_effective_permissions_writes();
+ + + + + = %L AND "LAST_OCCURRENCE" < %L;', + target_table, + columns, + columns, + source_table, + partition_date, + next_day + ); + + partition_date := next_day; + END LOOP; + END; + $$; + ]]> + + + + CREATE TABLE "PORTFOLIOMETRICS_NEW" + ( + "COMPONENTS" int4 NOT NULL, + "CRITICAL" int4 NOT NULL, + "FINDINGS_AUDITED" int4 NULL, + "FINDINGS_TOTAL" int4 NULL, + "FINDINGS_UNAUDITED" int4 NULL, + "FIRST_OCCURRENCE" timestamptz NOT NULL, + "HIGH" int4 NOT NULL, + "RISKSCORE" float8 NOT NULL, + "LAST_OCCURRENCE" timestamptz NOT NULL, + "LOW" int4 NOT NULL, + "MEDIUM" int4 NOT NULL, + "POLICYVIOLATIONS_AUDITED" int4 NULL, + "POLICYVIOLATIONS_FAIL" int4 NULL, + "POLICYVIOLATIONS_INFO" int4 NULL, + "POLICYVIOLATIONS_LICENSE_AUDITED" int4 NULL, + "POLICYVIOLATIONS_LICENSE_TOTAL" int4 NULL, + "POLICYVIOLATIONS_LICENSE_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_AUDITED" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_TOTAL" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_SECURITY_AUDITED" int4 NULL, + "POLICYVIOLATIONS_SECURITY_TOTAL" int4 NULL, + "POLICYVIOLATIONS_SECURITY_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_TOTAL" int4 NULL, + "POLICYVIOLATIONS_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_WARN" int4 NULL, + "PROJECTS" int4 NOT NULL, + "SUPPRESSED" int4 NOT NULL, + "UNASSIGNED_SEVERITY" int4 NULL, + "VULNERABILITIES" int4 NOT NULL, + "VULNERABLECOMPONENTS" int4 NOT NULL, + "VULNERABLEPROJECTS" int4 NOT NULL, + CONSTRAINT "PORTFOLIOMETRICS_NEW_PK" PRIMARY KEY ("LAST_OCCURRENCE") + ) PARTITION BY RANGE ("LAST_OCCURRENCE"); + + + + CREATE TABLE "PROJECTMETRICS_NEW" + ( + "COMPONENTS" int4 NOT NULL, + "CRITICAL" int4 NOT NULL, + "FINDINGS_AUDITED" int4 NULL, + "FINDINGS_TOTAL" int4 NULL, + "FINDINGS_UNAUDITED" int4 NULL, + "FIRST_OCCURRENCE" timestamptz NOT NULL, + "HIGH" int4 NOT NULL, + "RISKSCORE" float8 NOT NULL, + "LAST_OCCURRENCE" timestamptz NOT NULL, + "LOW" int4 NOT NULL, + "MEDIUM" int4 NOT NULL, + "POLICYVIOLATIONS_AUDITED" int4 NULL, + "POLICYVIOLATIONS_FAIL" int4 NULL, + "POLICYVIOLATIONS_INFO" int4 NULL, + "POLICYVIOLATIONS_LICENSE_AUDITED" int4 NULL, + "POLICYVIOLATIONS_LICENSE_TOTAL" int4 NULL, + "POLICYVIOLATIONS_LICENSE_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_AUDITED" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_TOTAL" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_SECURITY_AUDITED" int4 NULL, + "POLICYVIOLATIONS_SECURITY_TOTAL" int4 NULL, + "POLICYVIOLATIONS_SECURITY_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_TOTAL" int4 NULL, + "POLICYVIOLATIONS_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_WARN" int4 NULL, + "PROJECT_ID" int8 NOT NULL, + "SUPPRESSED" int4 NOT NULL, + "UNASSIGNED_SEVERITY" int4 NULL, + "VULNERABILITIES" int4 NOT NULL, + "VULNERABLECOMPONENTS" int4 NOT NULL, + CONSTRAINT "PROJECTMETRICS_NEW_PK" PRIMARY KEY ("PROJECT_ID", "LAST_OCCURRENCE") + ) PARTITION BY RANGE ("LAST_OCCURRENCE"); + + + + CREATE TABLE "DEPENDENCYMETRICS_NEW" + ( + "COMPONENT_ID" int8 NOT NULL, + "CRITICAL" int4 NOT NULL, + "FINDINGS_AUDITED" int4 NULL, + "FINDINGS_TOTAL" int4 NULL, + "FINDINGS_UNAUDITED" int4 NULL, + "FIRST_OCCURRENCE" timestamptz NOT NULL, + "HIGH" int4 NOT NULL, + "RISKSCORE" float8 NOT NULL, + "LAST_OCCURRENCE" timestamptz NOT NULL, + "LOW" int4 NOT NULL, + "MEDIUM" int4 NOT NULL, + "POLICYVIOLATIONS_AUDITED" int4 NULL, + "POLICYVIOLATIONS_FAIL" int4 NULL, + "POLICYVIOLATIONS_INFO" int4 NULL, + "POLICYVIOLATIONS_LICENSE_AUDITED" int4 NULL, + "POLICYVIOLATIONS_LICENSE_TOTAL" int4 NULL, + "POLICYVIOLATIONS_LICENSE_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_AUDITED" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_TOTAL" int4 NULL, + "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_SECURITY_AUDITED" int4 NULL, + "POLICYVIOLATIONS_SECURITY_TOTAL" int4 NULL, + "POLICYVIOLATIONS_SECURITY_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_TOTAL" int4 NULL, + "POLICYVIOLATIONS_UNAUDITED" int4 NULL, + "POLICYVIOLATIONS_WARN" int4 NULL, + "PROJECT_ID" int8 NOT NULL, + "SUPPRESSED" int4 NOT NULL, + "UNASSIGNED_SEVERITY" int4 NULL, + "VULNERABILITIES" int4 NOT NULL, + CONSTRAINT "DEPENDENCYMETRICS_NEW_PK" PRIMARY KEY ("PROJECT_ID", "COMPONENT_ID", "LAST_OCCURRENCE") + ) PARTITION BY RANGE ("LAST_OCCURRENCE"); + + + + + + + -- call the migration procedure + CALL "MIGRATE_METRICS_TO_PARTITIONS"('PORTFOLIOMETRICS_NEW'::TEXT, 'PORTFOLIOMETRICS'::TEXT, + '"COMPONENTS", "CRITICAL", "FINDINGS_AUDITED", "FINDINGS_TOTAL", "FINDINGS_UNAUDITED", "FIRST_OCCURRENCE", "HIGH", "RISKSCORE", "LAST_OCCURRENCE", "LOW", "MEDIUM", "POLICYVIOLATIONS_AUDITED", "POLICYVIOLATIONS_FAIL", "POLICYVIOLATIONS_INFO", "POLICYVIOLATIONS_LICENSE_AUDITED", "POLICYVIOLATIONS_LICENSE_TOTAL", "POLICYVIOLATIONS_LICENSE_UNAUDITED", "POLICYVIOLATIONS_OPERATIONAL_AUDITED", "POLICYVIOLATIONS_OPERATIONAL_TOTAL", "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED", "POLICYVIOLATIONS_SECURITY_AUDITED", "POLICYVIOLATIONS_SECURITY_TOTAL", "POLICYVIOLATIONS_SECURITY_UNAUDITED", "POLICYVIOLATIONS_TOTAL", "POLICYVIOLATIONS_UNAUDITED", "POLICYVIOLATIONS_WARN", "PROJECTS", "SUPPRESSED", "UNASSIGNED_SEVERITY", "VULNERABILITIES", "VULNERABLECOMPONENTS", "VULNERABLEPROJECTS"'); + + -- drop old table + DROP TABLE "PORTFOLIOMETRICS"; + + -- rename partitioned table + ALTER TABLE "PORTFOLIOMETRICS_NEW" RENAME TO "PORTFOLIOMETRICS"; + + -- rename PK + ALTER TABLE "PORTFOLIOMETRICS" RENAME CONSTRAINT "PORTFOLIOMETRICS_NEW_PK" TO "PORTFOLIOMETRICS_PK"; + + + + + + + -- call the migration procedure + CALL "MIGRATE_METRICS_TO_PARTITIONS"('PROJECTMETRICS_NEW'::TEXT, 'PROJECTMETRICS'::TEXT, + '"COMPONENTS", "CRITICAL", "FINDINGS_AUDITED", "FINDINGS_TOTAL", "FINDINGS_UNAUDITED", "FIRST_OCCURRENCE", "HIGH", "RISKSCORE", "LAST_OCCURRENCE", "LOW", "MEDIUM", "POLICYVIOLATIONS_AUDITED", "POLICYVIOLATIONS_FAIL", "POLICYVIOLATIONS_INFO", "POLICYVIOLATIONS_LICENSE_AUDITED", "POLICYVIOLATIONS_LICENSE_TOTAL", "POLICYVIOLATIONS_LICENSE_UNAUDITED", "POLICYVIOLATIONS_OPERATIONAL_AUDITED", "POLICYVIOLATIONS_OPERATIONAL_TOTAL", "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED", "POLICYVIOLATIONS_SECURITY_AUDITED", "POLICYVIOLATIONS_SECURITY_TOTAL", "POLICYVIOLATIONS_SECURITY_UNAUDITED", "POLICYVIOLATIONS_TOTAL", "POLICYVIOLATIONS_UNAUDITED", "POLICYVIOLATIONS_WARN", "PROJECT_ID", "SUPPRESSED", "UNASSIGNED_SEVERITY", "VULNERABILITIES", "VULNERABLECOMPONENTS"'); + + -- drop old table + DROP TABLE "PROJECTMETRICS"; + + -- rename partitioned table + ALTER TABLE "PROJECTMETRICS_NEW" RENAME TO "PROJECTMETRICS"; + + -- rename PK + ALTER TABLE "PROJECTMETRICS" RENAME CONSTRAINT "PROJECTMETRICS_NEW_PK" TO "PROJECTMETRICS_PK"; + + + + + + + -- call the migration procedure + CALL "MIGRATE_METRICS_TO_PARTITIONS"('DEPENDENCYMETRICS_NEW'::TEXT, 'DEPENDENCYMETRICS'::TEXT, + '"COMPONENT_ID", "CRITICAL", "FINDINGS_AUDITED", "FINDINGS_TOTAL", "FINDINGS_UNAUDITED", "FIRST_OCCURRENCE", "HIGH", "RISKSCORE", "LAST_OCCURRENCE", "LOW", "MEDIUM", "POLICYVIOLATIONS_AUDITED", "POLICYVIOLATIONS_FAIL", "POLICYVIOLATIONS_INFO", "POLICYVIOLATIONS_LICENSE_AUDITED", "POLICYVIOLATIONS_LICENSE_TOTAL", "POLICYVIOLATIONS_LICENSE_UNAUDITED", "POLICYVIOLATIONS_OPERATIONAL_AUDITED", "POLICYVIOLATIONS_OPERATIONAL_TOTAL", "POLICYVIOLATIONS_OPERATIONAL_UNAUDITED", "POLICYVIOLATIONS_SECURITY_AUDITED", "POLICYVIOLATIONS_SECURITY_TOTAL", "POLICYVIOLATIONS_SECURITY_UNAUDITED", "POLICYVIOLATIONS_TOTAL", "POLICYVIOLATIONS_UNAUDITED", "POLICYVIOLATIONS_WARN", "PROJECT_ID", "SUPPRESSED", "UNASSIGNED_SEVERITY", "VULNERABILITIES"'); + + -- drop old table + DROP TABLE "DEPENDENCYMETRICS"; + + -- rename partitioned table + ALTER TABLE "DEPENDENCYMETRICS_NEW" RENAME TO "DEPENDENCYMETRICS"; + + -- rename PK + ALTER TABLE "DEPENDENCYMETRICS" RENAME CONSTRAINT "DEPENDENCYMETRICS_NEW_PK" TO "DEPENDENCYMETRICS_PK"; + + + + + + + + + + + + + + + + SET CONSTRAINTS ALL IMMEDIATE + + + + + + + + + + DROP INDEX IF EXISTS "TAG_NAME_IDX" + + + + CREATE TEMPORARY TABLE tmp_duplicate_tag + ON COMMIT DROP + AS + SELECT "NAME" AS name + , MIN("ID") AS canonical_id + FROM "TAG" + GROUP BY "NAME" + HAVING COUNT(*) > 1; + + + + + CREATE FUNCTION cleanup_duplicate_tag_relationships( + table_name TEXT, + relation_id_column TEXT + ) + RETURNS void AS $$ + BEGIN + EXECUTE format($q$ + UPDATE %1$I AS tag_relationship + SET "TAG_ID" = tmp_duplicate_tag.canonical_id + FROM tmp_duplicate_tag + INNER JOIN "TAG" + ON "TAG"."NAME" = tmp_duplicate_tag.name + AND "TAG"."ID" != tmp_duplicate_tag.canonical_id + WHERE tag_relationship."TAG_ID" = "TAG"."ID"; + $q$, table_name, relation_id_column + ); + + EXECUTE format($q$ + WITH cte_dupe AS ( + SELECT "TAG_ID" + , %2$I + FROM %1$I AS tag_relationship + GROUP BY "TAG_ID" + , %2$I + HAVING COUNT(*) > 1 + ), + cte_deleted_dupe AS ( + DELETE FROM %1$I AS tag_relationship + USING cte_dupe + WHERE tag_relationship."TAG_ID" = cte_dupe."TAG_ID" + AND tag_relationship.%2$I = cte_dupe.%2$I + RETURNING tag_relationship."TAG_ID" + , tag_relationship.%2$I + ) + INSERT INTO %1$I ("TAG_ID", %2$I) + SELECT DISTINCT "TAG_ID", %2$I FROM cte_deleted_dupe; + $q$, table_name, relation_id_column + ); + END; + $$ LANGUAGE plpgsql; + + + + DO $$ + BEGIN + PERFORM cleanup_duplicate_tag_relationships('NOTIFICATIONRULE_TAGS', 'NOTIFICATIONRULE_ID'); + PERFORM cleanup_duplicate_tag_relationships('POLICY_TAGS', 'POLICY_ID'); + PERFORM cleanup_duplicate_tag_relationships('PROJECTS_TAGS', 'PROJECT_ID'); + PERFORM cleanup_duplicate_tag_relationships('VULNERABILITIES_TAGS', 'VULNERABILITY_ID'); + END + $$; + + + + DROP FUNCTION cleanup_duplicate_tag_relationships; + + DELETE FROM "TAG" + USING tmp_duplicate_tag + WHERE "TAG"."NAME" = tmp_duplicate_tag.name + AND "TAG"."ID" != tmp_duplicate_tag.canonical_id; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- Helper function to recalculate all user permissions for a project. + -- Called by trigger functions to update the values in the USER_PROJECT_EFFECTIVE_PERMISSIONS table. + CREATE OR REPLACE FUNCTION recalc_user_project_role_effective_permissions(project_ids BIGINT[]) + RETURNS void AS $$ + DECLARE + tbl_prefix TEXT; + BEGIN + -- Remove any existing effective permissions for this project + DELETE FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" + WHERE "PROJECT_ID" = ANY(project_ids); + + -- Rebuild effective permissions for all users + INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" + ("USER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") + SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" + FROM "USERS_PROJECTS_ROLES" upr + INNER JOIN "ROLES_PERMISSIONS" rp + ON rp."ROLE_ID" = upr."ROLE_ID" + INNER JOIN "PERMISSION" p + ON p."ID" = rp."PERMISSION_ID" + WHERE upr."PROJECT_ID" = ANY(project_ids); + END; + $$ LANGUAGE plpgsql; + + + + CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_delete() + RETURNS TRIGGER AS $$ + DECLARE + project_ids BIGINT[]; + role_ids BIGINT[]; + BEGIN + SELECT ARRAY_AGG(DISTINCT "ROLE_ID") + INTO role_ids + FROM old_table; + + IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN + SELECT ARRAY_AGG(sub."PROJECT_ID") + INTO project_ids + FROM ( + SELECT upr."PROJECT_ID" + FROM "USERS_PROJECTS_ROLES" upr + INNER JOIN old_table + ON old_table."ROLE_ID" = upr."ROLE_ID" + ) sub; + ELSE + SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") + INTO project_ids + FROM "USERS_PROJECTS_ROLES" + WHERE "ROLE_ID" = ANY(role_ids); + END IF; + + PERFORM recalc_user_project_role_effective_permissions(project_ids); + RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + + + CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_insert() + RETURNS TRIGGER AS $$ + DECLARE + project_ids BIGINT[]; + role_ids BIGINT[]; + BEGIN + SELECT ARRAY_AGG(DISTINCT "ROLE_ID") + INTO role_ids + FROM new_table; + + IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN + SELECT ARRAY_AGG(sub."PROJECT_ID") + INTO project_ids + FROM ( + SELECT upr."PROJECT_ID" + FROM "USERS_PROJECTS_ROLES" upr + INNER JOIN new_table + ON new_table."ROLE_ID" = upr."ROLE_ID" + ) sub; + ELSE + SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") + INTO project_ids + FROM "USERS_PROJECTS_ROLES" + WHERE "ROLE_ID" = ANY(role_ids); + END IF; + + PERFORM recalc_user_project_role_effective_permissions(project_ids); + RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + + + CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_update() + RETURNS TRIGGER AS $$ + DECLARE + project_ids BIGINT[]; + role_ids BIGINT[]; + BEGIN + SELECT ARRAY_AGG("ROLE_ID") + INTO role_ids + FROM ( + SELECT "ROLE_ID" FROM old_table + UNION + SELECT "ROLE_ID" FROM new_table + ) roles; + + IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN + SELECT ARRAY_AGG(sub."PROJECT_ID") + INTO project_ids + FROM ( + SELECT upr."PROJECT_ID" + FROM "USERS_PROJECTS_ROLES" upr + INNER JOIN new_table + ON new_table."ROLE_ID" = upr."ROLE_ID" + FULL OUTER JOIN old_table + ON new_table."ROLE_ID" = old_table."ROLE_ID" + ) sub; + ELSE + SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") + INTO project_ids + FROM "USERS_PROJECTS_ROLES" + WHERE "ROLE_ID" = ANY(role_ids); + END IF; + + PERFORM recalc_user_project_role_effective_permissions(project_ids); + RETURN NULL; + END; + $$ LANGUAGE plpgsql; + + + + -- INSERT trigger for USERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_insert + AFTER INSERT ON "USERS_PROJECTS_ROLES" + REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); + + -- DELETE trigger for USERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_delete + AFTER DELETE ON "USERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); + + -- UPDATE trigger for USERS_PROJECTS_ROLES + CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_update + AFTER UPDATE ON "USERS_PROJECTS_ROLES" + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_update(); + + -- INSERT trigger for ROLES_PERMISSIONS + CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_insert + AFTER INSERT ON "ROLES_PERMISSIONS" + REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); + + -- DELETE trigger for ROLES_PERMISSIONS + CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_delete + AFTER DELETE ON "ROLES_PERMISSIONS" + REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT + EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); + + -- UPDATE trigger for ROLES_PERMISSIONS + CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_update + AFTER UPDATE ON "ROLES_PERMISSIONS" + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT + EXECUTE FUNCTION effective_permissions_mx_on_update(); + + diff --git a/src/main/resources/migration/changelog-v5.6.0-roles.xml b/src/main/resources/migration/changelog-v5.6.0-roles.xml deleted file mode 100644 index 8e69187b15..0000000000 --- a/src/main/resources/migration/changelog-v5.6.0-roles.xml +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- Helper function to recalculate all user permissions for a project. - -- Called by trigger functions to update the values in the USER_PROJECT_EFFECTIVE_PERMISSIONS table. - CREATE OR REPLACE FUNCTION recalc_user_project_role_effective_permissions(project_ids BIGINT[]) - RETURNS void AS $$ - DECLARE - tbl_prefix TEXT; - BEGIN - -- Remove any existing effective permissions for this project - DELETE FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" - WHERE "PROJECT_ID" = ANY(project_ids); - - -- Rebuild effective permissions for all users - INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" - ("USER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") - SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" - FROM "USERS_PROJECTS_ROLES" upr - INNER JOIN "ROLES_PERMISSIONS" rp - ON rp."ROLE_ID" = upr."ROLE_ID" - INNER JOIN "PERMISSION" p - ON p."ID" = rp."PERMISSION_ID" - WHERE upr."PROJECT_ID" = ANY(project_ids); - END; - $$ LANGUAGE plpgsql; - - - - CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_delete() - RETURNS TRIGGER AS $$ - DECLARE - project_ids BIGINT[]; - role_ids BIGINT[]; - BEGIN - SELECT ARRAY_AGG(DISTINCT "ROLE_ID") - INTO role_ids - FROM old_table; - - IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN - SELECT ARRAY_AGG(sub."PROJECT_ID") - INTO project_ids - FROM ( - SELECT upr."PROJECT_ID" - FROM "USERS_PROJECTS_ROLES" upr - INNER JOIN old_table - ON old_table."ROLE_ID" = upr."ROLE_ID" - ) sub; - ELSE - SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") - INTO project_ids - FROM "USERS_PROJECTS_ROLES" - WHERE "ROLE_ID" = ANY(role_ids); - END IF; - - PERFORM recalc_user_project_role_effective_permissions(project_ids); - RETURN NULL; - END; - $$ LANGUAGE plpgsql; - - - - CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_insert() - RETURNS TRIGGER AS $$ - DECLARE - project_ids BIGINT[]; - role_ids BIGINT[]; - BEGIN - SELECT ARRAY_AGG(DISTINCT "ROLE_ID") - INTO role_ids - FROM new_table; - - IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN - SELECT ARRAY_AGG(sub."PROJECT_ID") - INTO project_ids - FROM ( - SELECT upr."PROJECT_ID" - FROM "USERS_PROJECTS_ROLES" upr - INNER JOIN new_table - ON new_table."ROLE_ID" = upr."ROLE_ID" - ) sub; - ELSE - SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") - INTO project_ids - FROM "USERS_PROJECTS_ROLES" - WHERE "ROLE_ID" = ANY(role_ids); - END IF; - - PERFORM recalc_user_project_role_effective_permissions(project_ids); - RETURN NULL; - END; - $$ LANGUAGE plpgsql; - - - - CREATE OR REPLACE FUNCTION role_effective_permissions_mx_on_update() - RETURNS TRIGGER AS $$ - DECLARE - project_ids BIGINT[]; - role_ids BIGINT[]; - BEGIN - SELECT ARRAY_AGG("ROLE_ID") - INTO role_ids - FROM ( - SELECT "ROLE_ID" FROM old_table - UNION - SELECT "ROLE_ID" FROM new_table - ) roles; - - IF TG_TABLE_NAME = 'ROLES_PERMISSIONS' THEN - SELECT ARRAY_AGG(sub."PROJECT_ID") - INTO project_ids - FROM ( - SELECT upr."PROJECT_ID" - FROM "USERS_PROJECTS_ROLES" upr - INNER JOIN new_table - ON new_table."ROLE_ID" = upr."ROLE_ID" - FULL OUTER JOIN old_table - ON new_table."ROLE_ID" = old_table."ROLE_ID" - ) sub; - ELSE - SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") - INTO project_ids - FROM "USERS_PROJECTS_ROLES" - WHERE "ROLE_ID" = ANY(role_ids); - END IF; - - PERFORM recalc_user_project_role_effective_permissions(project_ids); - RETURN NULL; - END; - $$ LANGUAGE plpgsql; - - - - -- INSERT trigger for USERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_insert - AFTER INSERT ON "USERS_PROJECTS_ROLES" - REFERENCING NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); - - -- DELETE trigger for USERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_delete - AFTER DELETE ON "USERS_PROJECTS_ROLES" - REFERENCING OLD TABLE AS old_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); - - -- UPDATE trigger for USERS_PROJECTS_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_update - AFTER UPDATE ON "USERS_PROJECTS_ROLES" - REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_update(); - - -- INSERT trigger for ROLES_PERMISSIONS - CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_insert - AFTER INSERT ON "ROLES_PERMISSIONS" - REFERENCING NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); - - -- DELETE trigger for ROLES_PERMISSIONS - CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_delete - AFTER DELETE ON "ROLES_PERMISSIONS" - REFERENCING OLD TABLE AS old_table - FOR EACH STATEMENT - EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); - - -- UPDATE trigger for ROLES_PERMISSIONS - CREATE TRIGGER trigger_effective_permissions_mx_on_roles_permissions_update - AFTER UPDATE ON "ROLES_PERMISSIONS" - REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT - EXECUTE FUNCTION effective_permissions_mx_on_update(); - - - From a922bba37d9762f88098cd26ef07da5c34b02d3c Mon Sep 17 00:00:00 2001 From: emeremikwu-lm Date: Fri, 23 May 2025 12:33:47 -0500 Subject: [PATCH 24/45] Endpoint request changes and unittests (#26) Signed-off-by: emeremikwu-lm --- .../persistence/jdbi/RoleDao.java | 11 ++ .../resources/v1/UserResource.java | 156 +++++++++--------- 2 files changed, 88 insertions(+), 79 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java index 24237aef9e..0af0eb5ec5 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -88,6 +88,17 @@ public interface RoleDao { @RegisterRowMapper(ProjectRoleRowMapper.class) List getUserRoles(@Bind String username); + @SqlQuery(/* language=sql */ """ + SELECT EXISTS ( + SELECT 1 + FROM "USERS_PROJECTS_ROLES" + WHERE "ROLE_ID" = :roleId + AND "PROJECT_ID" = :projectId + AND "USER_ID" = :userId + ) + """) + boolean userProjectRoleExists(@Bind long userId, @Bind long projectId, @Bind long roleId); + @SqlQuery(/* language=sql */ """ SELECT p."ID", p."NAME", p."UUID" FROM "PROJECT" p diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index abc22709ae..9adbfd6a96 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -75,6 +75,8 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import javax.jdo.Query; +import org.dependencytrack.persistence.jdbi.JdbiFactory; +import org.dependencytrack.persistence.jdbi.RoleDao; import java.security.Principal; import java.util.ArrayList; import java.util.Collections; @@ -850,121 +852,117 @@ private UserSubject buildUserSubject(final String username, final String email) return userBuilder.build(); } - @POST - @Path("/{username}/role") + @SuppressWarnings("null") + @PUT + @Path("/role") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( - summary = "Adds role to specific user.", + summary = "Assigns or updates a user's role for a project.", description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse( responseCode = "200", - description = "Updated user with a specific role", - content = @Content(schema = @Schema(implementation = User.class)) - ), - @ApiResponse(responseCode = "304", description = "The user has already been assigned to this role."), + description = "User with the specified role assigned or updated", + content = @Content(schema = @Schema(implementation = User.class))), + @ApiResponse(responseCode = "304", description = "The user already has this role for the project."), @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse(responseCode = "404", description = "The user or role could not be found") + @ApiResponse( + responseCode = "404", + description = "The user, role, or project could not be found", + content = @Content(schema = @Schema(implementation = AccessManagementProblemDetails.class)) + ) }) - @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) - public Response addRoleToUser( - @Parameter(description = "A valid username", required = true) - @PathParam("username") - String username, + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) + public Response assignProjectRoleToUser( + @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { + try (QueryManager qm = new QueryManager()) { + final Role role = qm.getObjectByUuid(Role.class, request.role()); + final User user = qm.getUser(request.username()); + final Project project = qm.getProject(request.project()); - @Parameter(description = "The UUID of the role to associate username with", required = true) - IdentifiableObject identifiableObject, + List problems = new ArrayList<>(); + if (role == null) problems.add("role"); + if (user == null) problems.add("user"); + if (project == null) problems.add("project"); - @Parameter(description = "The name of the project", required = true) - @QueryParam("projectName") - String projectName, - - @Parameter(description = "The version of the project") - @QueryParam("projectVersion") - String projectVersion) { - try (QueryManager qm = new QueryManager()) { - final Role role = qm.getObjectByUuid(Role.class, identifiableObject.getUuid()); - if (role == null) - return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + if (!problems.isEmpty()) { + ProblemDetails problem = new AccessManagementProblemDetails( + Response.Status.NOT_FOUND.getStatusCode(), + "Invalid role, user or project", + "One or more variables could not be found", + problems); - User user = qm.getUser(username); - if (user == null) - return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); + return problem.toResponse(); + } - Project project = qm.getProject(projectName, projectVersion); - if (project == null) - return Response.status(Response.Status.NOT_FOUND).entity("The project could not be found.").build(); + boolean exists = JdbiFactory.withJdbiHandle(getAlpineRequest(), handle -> handle.attach(RoleDao.class) + .userProjectRoleExists(user.getId(), project.getId(), role.getId())); + if (exists) return Response.notModified().build(); - final boolean modified = qm.addRoleToUser(user, role, project); - if (!modified) - return Response.notModified().entity("The user is already a member of the specified role.").build(); + qm.addRoleToUser(user, role, project); principal = qm.getObjectById(principal.getClass(), principal.getId()); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, - "Added role membership for: %s / role: %s / project: %s" - .formatted(user.getName(), role.getName(), project.getName())); + "Granted project role: user='%s', role='%s', project='%s'" + .formatted(user.getUsername(), role.getName(), project.getName())); return Response.ok(user).build(); } } + @SuppressWarnings("null") @DELETE - @Path("/{username}/role") + @Path("/role") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( - summary = "Removes role from specific user.", + summary = "Removes a specific role for a user from a project.", description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" -) + ) @ApiResponses(value = { @ApiResponse( - responseCode = "200", - description = "Updated user with a specific role removed", - content = @Content(schema = @Schema(implementation = User.class))), - @ApiResponse(responseCode = "204", description = "The role has been successfully removed from the user"), - @ApiResponse(responseCode = "304", description = "The user is not a member of the specified role"), + responseCode = "204", + description = "The specified role was successfully removed from the user" + ), + @ApiResponse(responseCode = "304", description = "The user is not a member of the specified role for the project"), @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse(responseCode = "404", description = "The user or role could not be found") -}) - @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) - public Response removeRoleFromUser( - @Parameter(description = "A valid username", required = true) - @PathParam("username") - String username, - - @Parameter(description = "The UUID of the role to associate username with", required = true) - IdentifiableObject identifiableObject, - - @Parameter(description = "The name of the project", required = true) - @QueryParam("projectName") - String projectName, - - @Parameter(description = "The version of the project") - @QueryParam("projectVersion") - String projectVersion) { + @ApiResponse( + responseCode = "404", + description = "The user, role, or project could not be found", + content = @Content(schema = @Schema(implementation = AccessManagementProblemDetails.class)) + ) + }) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) + public Response removeProjectRoleFromUser( + @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { try (QueryManager qm = new QueryManager()) { - final Role role = qm.getObjectByUuid(Role.class, identifiableObject.getUuid()); - if (role == null) - return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + final Role role = qm.getObjectByUuid(Role.class, request.role()); + final User user = qm.getUser(request.username()); + final Project project = qm.getProject(request.project()); - User user = qm.getUser(username); - if (user == null) - return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); + final List problems = new ArrayList<>(); + if (role == null) problems.add("role"); + if (user == null) problems.add("user"); + if (project == null) problems.add("project"); - Project project = qm.getProject(projectName, projectVersion); - if (project == null) - return Response.status(Response.Status.NOT_FOUND).entity("The project could not be found.").build(); + if (!problems.isEmpty()) { + ProblemDetails problem = new AccessManagementProblemDetails( + Response.Status.NOT_FOUND.getStatusCode(), + "Invalid role, user or project", + "One or more variables could not be found", + problems); + + return problem.toResponse(); + } - final boolean modified = qm.removeRoleFromUser(user, role, project); - if (!modified) - return Response.notModified().entity("The user is not a member of the specified role.").build(); + boolean removed = qm.removeRoleFromUser(user, role, project); + if (!removed) return Response.notModified().build(); - user = qm.getObjectById(user.getClass(), user.getId()); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, - "Removed role membership for: %s / role: %s / project: %s" - .formatted(user.getName(), role.getName(), project.getName())); + "Revoked project role: user='%s', role='%s', project='%s'" + .formatted(user.getUsername(), role.getName(), project.getName())); return Response.noContent().build(); } @@ -1025,7 +1023,7 @@ public Response setUserTeams( user.setTeams(requestedTeams); qm.persist(user); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, - "Added team membership for: " + user.getName() + " / team: " + requestedTeams.toString()); + "Added team membership for: " + user.getUsername() + " / team: " + requestedTeams.toString()); return Response.ok(user).build(); } } From 8b8f1e95be5a38e1068cbb9d280f404da09255cf Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Fri, 23 May 2025 14:12:46 -0500 Subject: [PATCH 25/45] chore: clean up rebase Signed-off-by: Jonathan Howard --- .../persistence/AlpineQueryManager.java | 9 +- .../main/java/alpine/model/Permission.java | 2 +- .../src/main/java/alpine/model/Team.java | 3 +- apiserver/pom.xml | 4 +- .../org/dependencytrack/auth/Permissions.java | 10 - .../dependencytrack/model/ProjectRole.java | 3 - .../java/org/dependencytrack/model/Role.java | 12 +- .../persistence/DefaultObjectGenerator.java | 141 ++- .../persistence/ProjectQueryManager.java | 28 +- .../persistence/QueryManager.java | 20 +- .../persistence/RoleQueryManager.java | 65 +- .../persistence/jdbi/RoleDao.java | 20 +- .../jdbi/mapping/ProjectRoleRowMapper.java | 10 +- .../jdbi/mapping/ProjectRowMapper.java | 88 ++ .../resources/v1/AccessControlResource.java | 2 +- .../resources/v1/PermissionResource.java | 111 ++- .../resources/v1/RoleResource.java | 27 +- .../resources/v1/TeamResource.java | 2 +- .../resources/v1/UserResource.java | 6 +- .../resources/v1/vo/CreateRoleRequest.java | 47 + .../resources/v1/vo/RoleProjectRequest.java | 47 + .../main/resources/META-INF/persistence.xml | 6 +- .../org/dependencytrack/ResourceTest.java | 1 + .../v1/NotificationRuleResourceTest.java | 3 +- .../resources/v1/PermissionResourceTest.java | 2 +- .../resources/v1/TeamResourceTest.java | 2 +- .../v1/UserResourceAuthenticatedTest.java | 103 ++ persistence-jooq/pom.xml | 4 +- .../jooq/generated/DefaultSchema.java | 25 +- .../persistence/jooq/generated/Indexes.java | 8 +- .../persistence/jooq/generated/Keys.java | 17 +- .../persistence/jooq/generated/Routines.java | 16 +- .../persistence/jooq/generated/Tables.java | 20 +- .../jooq/generated/enums/Severity.java | 2 +- .../generated/routines/CalcRiskScore.java | 4 +- .../generated/routines/HasProjectAccess.java | 4 +- .../generated/routines/JsonbVulnAliases.java | 4 +- ...RecalcUserProjectEffectivePermissions.java | 4 +- ...lcUserProjectRoleEffectivePermissions.java | 54 ++ .../routines/UpdateComponentMetrics.java | 4 +- .../routines/UpdatePortfolioMetrics.java | 4 +- .../routines/UpdateProjectMetrics.java | 4 +- .../tables/AffectedVersionAttribution.java | 8 +- .../jooq/generated/tables/Analysis.java | 8 +- .../generated/tables/AnalysisComment.java | 8 +- .../jooq/generated/tables/ApiKey.java | 8 +- .../jooq/generated/tables/ApiKeysTeams.java | 8 +- .../jooq/generated/tables/Bom.java | 8 +- .../jooq/generated/tables/Component.java | 8 +- .../generated/tables/ComponentOccurrence.java | 8 +- .../generated/tables/ComponentProperty.java | 8 +- .../tables/ComponentsVulnerabilities.java | 8 +- .../jooq/generated/tables/ConfigProperty.java | 4 +- .../generated/tables/DependencyMetrics.java | 8 +- .../jooq/generated/tables/Epss.java | 4 +- .../generated/tables/FindingAttribution.java | 8 +- .../generated/tables/IntegrityAnalysis.java | 8 +- .../tables/IntegrityMetaComponent.java | 4 +- .../jooq/generated/tables/License.java | 8 +- .../jooq/generated/tables/LicenseGroup.java | 8 +- .../generated/tables/LicenseGroupLicense.java | 8 +- .../generated/tables/MappedLdapGroup.java | 8 +- .../generated/tables/MappedOidcGroup.java | 8 +- .../tables/NotificationPublisher.java | 8 +- .../generated/tables/NotificationRule.java | 8 +- .../tables/NotificationRuleProjects.java | 8 +- .../tables/NotificationRuleTags.java | 8 +- .../tables/NotificationRuleTeams.java | 8 +- .../jooq/generated/tables/OidcGroup.java | 8 +- .../jooq/generated/tables/Permission.java | 30 +- .../jooq/generated/tables/Policy.java | 8 +- .../generated/tables/PolicyCondition.java | 8 +- .../jooq/generated/tables/PolicyProjects.java | 8 +- .../jooq/generated/tables/PolicyTags.java | 8 +- .../generated/tables/PolicyViolation.java | 8 +- .../generated/tables/PortfolioMetrics.java | 4 +- .../jooq/generated/tables/Project.java | 22 +- .../generated/tables/ProjectAccessTeams.java | 8 +- .../generated/tables/ProjectHierarchy.java | 8 +- .../generated/tables/ProjectMetadata.java | 8 +- .../jooq/generated/tables/ProjectMetrics.java | 8 +- .../generated/tables/ProjectProperty.java | 8 +- .../jooq/generated/tables/ProjectsTags.java | 8 +- .../jooq/generated/tables/Repository.java | 4 +- .../tables/RepositoryMetaComponent.java | 4 +- .../jooq/generated/tables/Role.java | 333 +++++++ .../generated/tables/RolesPermissions.java | 317 ++++++ .../generated/tables/ServiceComponent.java | 8 +- .../ServiceComponentsVulnerabilities.java | 8 +- .../jooq/generated/tables/Tag.java | 8 +- .../jooq/generated/tables/Team.java | 8 +- .../generated/tables/TeamsPermissions.java | 8 +- .../jooq/generated/tables/User.java | 22 +- .../UserProjectEffectivePermissions.java | 8 +- .../generated/tables/UsersPermissions.java | 8 +- .../generated/tables/UsersProjectsRoles.java | 329 +++++++ .../jooq/generated/tables/UsersTeams.java | 8 +- .../jooq/generated/tables/Vex.java | 8 +- .../generated/tables/ViolationAnalysis.java | 8 +- .../tables/ViolationAnalysisComment.java | 8 +- .../generated/tables/VulnerabilitiesTags.java | 8 +- .../jooq/generated/tables/Vulnerability.java | 8 +- .../generated/tables/VulnerabilityAlias.java | 4 +- .../tables/VulnerabilityMetrics.java | 4 +- .../generated/tables/VulnerabilityPolicy.java | 8 +- .../tables/VulnerabilityPolicyBundle.java | 4 +- .../generated/tables/VulnerabilityScan.java | 4 +- .../generated/tables/VulnerableSoftware.java | 8 +- .../VulnerableSoftwareVulnerabilities.java | 8 +- .../jooq/generated/tables/WorkflowState.java | 8 +- .../AffectedVersionAttributionRecord.java | 4 +- .../tables/records/AnalysisCommentRecord.java | 4 +- .../tables/records/AnalysisRecord.java | 4 +- .../tables/records/ApiKeyRecord.java | 4 +- .../tables/records/ApiKeysTeamsRecord.java | 4 +- .../generated/tables/records/BomRecord.java | 4 +- .../records/ComponentOccurrenceRecord.java | 4 +- .../records/ComponentPropertyRecord.java | 4 +- .../tables/records/ComponentRecord.java | 4 +- .../ComponentsVulnerabilitiesRecord.java | 4 +- .../tables/records/ConfigPropertyRecord.java | 4 +- .../records/DependencyMetricsRecord.java | 4 +- .../generated/tables/records/EpssRecord.java | 4 +- .../records/FindingAttributionRecord.java | 4 +- .../records/IntegrityAnalysisRecord.java | 4 +- .../records/IntegrityMetaComponentRecord.java | 4 +- .../records/LicenseGroupLicenseRecord.java | 4 +- .../tables/records/LicenseGroupRecord.java | 4 +- .../tables/records/LicenseRecord.java | 4 +- .../tables/records/MappedLdapGroupRecord.java | 4 +- .../tables/records/MappedOidcGroupRecord.java | 4 +- .../records/NotificationPublisherRecord.java | 4 +- .../NotificationRuleProjectsRecord.java | 4 +- .../records/NotificationRuleRecord.java | 4 +- .../records/NotificationRuleTagsRecord.java | 4 +- .../records/NotificationRuleTeamsRecord.java | 4 +- .../tables/records/OidcGroupRecord.java | 4 +- .../tables/records/PermissionRecord.java | 4 +- .../tables/records/PolicyConditionRecord.java | 4 +- .../tables/records/PolicyProjectsRecord.java | 4 +- .../tables/records/PolicyRecord.java | 4 +- .../tables/records/PolicyTagsRecord.java | 4 +- .../tables/records/PolicyViolationRecord.java | 4 +- .../records/PortfolioMetricsRecord.java | 4 +- .../records/ProjectAccessTeamsRecord.java | 4 +- .../records/ProjectHierarchyRecord.java | 4 +- .../tables/records/ProjectMetadataRecord.java | 4 +- .../tables/records/ProjectMetricsRecord.java | 4 +- .../tables/records/ProjectPropertyRecord.java | 4 +- .../tables/records/ProjectRecord.java | 4 +- .../tables/records/ProjectsTagsRecord.java | 4 +- .../RepositoryMetaComponentRecord.java | 4 +- .../tables/records/RepositoryRecord.java | 4 +- .../generated/tables/records/RoleRecord.java | 108 +++ .../records/RolesPermissionsRecord.java | 80 ++ .../records/ServiceComponentRecord.java | 4 +- ...erviceComponentsVulnerabilitiesRecord.java | 4 +- .../generated/tables/records/TagRecord.java | 4 +- .../generated/tables/records/TeamRecord.java | 4 +- .../records/TeamsPermissionsRecord.java | 4 +- ...UserProjectEffectivePermissionsRecord.java | 4 +- .../generated/tables/records/UserRecord.java | 4 +- .../records/UsersPermissionsRecord.java | 4 +- .../records/UsersProjectsRolesRecord.java | 96 ++ .../tables/records/UsersTeamsRecord.java | 4 +- .../generated/tables/records/VexRecord.java | 4 +- .../ViolationAnalysisCommentRecord.java | 4 +- .../records/ViolationAnalysisRecord.java | 4 +- .../records/VulnerabilitiesTagsRecord.java | 4 +- .../records/VulnerabilityAliasRecord.java | 4 +- .../records/VulnerabilityMetricsRecord.java | 4 +- .../VulnerabilityPolicyBundleRecord.java | 4 +- .../records/VulnerabilityPolicyRecord.java | 4 +- .../tables/records/VulnerabilityRecord.java | 4 +- .../records/VulnerabilityScanRecord.java | 4 +- .../records/VulnerableSoftwareRecord.java | 4 +- ...lnerableSoftwareVulnerabilitiesRecord.java | 4 +- .../tables/records/WorkflowStateRecord.java | 4 +- .../resources/migration/changelog-v5.6.0.xml | 71 +- .../persistence/DefaultObjectGenerator.java | 401 -------- .../persistence/RoleQueryManager.java | 208 ---- .../persistence/jdbi/RoleDao.java | 126 --- .../resources/migration/changelog-v5.6.0.xml | 918 ------------------ .../function_has-project-access.sql | 54 -- 184 files changed, 2467 insertions(+), 2312 deletions(-) create mode 100644 apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java create mode 100644 apiserver/src/main/java/org/dependencytrack/resources/v1/vo/CreateRoleRequest.java create mode 100644 apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersProjectsRoles.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersProjectsRolesRecord.java delete mode 100644 src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java delete mode 100644 src/main/java/org/dependencytrack/persistence/RoleQueryManager.java delete mode 100644 src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java delete mode 100644 src/main/resources/migration/changelog-v5.6.0.xml delete mode 100644 src/main/resources/migration/procedures/function_has-project-access.sql diff --git a/alpine/alpine-infra/src/main/java/alpine/persistence/AlpineQueryManager.java b/alpine/alpine-infra/src/main/java/alpine/persistence/AlpineQueryManager.java index 840fef2b37..eee19833be 100644 --- a/alpine/alpine-infra/src/main/java/alpine/persistence/AlpineQueryManager.java +++ b/alpine/alpine-infra/src/main/java/alpine/persistence/AlpineQueryManager.java @@ -50,6 +50,8 @@ import java.util.Map; import java.util.Set; +import org.datanucleus.store.rdbms.query.JDOQLQuery; + /** * This QueryManager provides a concrete extension of {@link AbstractAlpineQueryManager} by * providing methods that operate on the default Alpine models such as ManagedUser and Team. @@ -537,8 +539,11 @@ public List getManagedUsers() { * @since 1.0.0 */ public User getUser(String username) { - final Query query = pm.newQuery(User.class, "username == :username"); - query.setParameters(username); + final Query query = pm.newQuery(User.class) + .filter("username == :username") + .setNamedParameters(Map.of("username", username)) + .extension(JDOQLQuery.EXTENSION_CANDIDATE_DONT_RESTRICT_DISCRIMINATOR, true); + return executeAndCloseUnique(query); } diff --git a/alpine/alpine-model/src/main/java/alpine/model/Permission.java b/alpine/alpine-model/src/main/java/alpine/model/Permission.java index 87edb5df62..01b0c074dd 100644 --- a/alpine/alpine-model/src/main/java/alpine/model/Permission.java +++ b/alpine/alpine-model/src/main/java/alpine/model/Permission.java @@ -45,7 +45,7 @@ * @since 1.0.0 */ @PersistenceCapable -@JsonInclude(JsonInclude.Include.NON_EMPTY) +@JsonInclude(JsonInclude.Include.NON_NULL) public class Permission implements Serializable { private static final long serialVersionUID = 1420020753285692448L; diff --git a/alpine/alpine-model/src/main/java/alpine/model/Team.java b/alpine/alpine-model/src/main/java/alpine/model/Team.java index 247993f55a..57b58b2492 100644 --- a/alpine/alpine-model/src/main/java/alpine/model/Team.java +++ b/alpine/alpine-model/src/main/java/alpine/model/Team.java @@ -60,7 +60,7 @@ @Persistent(name = "mappedOidcGroups"), @Persistent(name = "permissions") }) -@JsonInclude(JsonInclude.Include.NON_EMPTY) +@JsonInclude(JsonInclude.Include.NON_NULL) public class Team implements Serializable { private static final long serialVersionUID = 6938424919898277944L; @@ -97,6 +97,7 @@ public enum FetchGroup { @Persistent(mappedBy = "teams") @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) + @JsonIgnore private List users; @Persistent(mappedBy = "team") diff --git a/apiserver/pom.xml b/apiserver/pom.xml index 218d133081..b7c3ccb8cc 100644 --- a/apiserver/pom.xml +++ b/apiserver/pom.xml @@ -43,8 +43,8 @@ 0.5.3.2 3.2.4 2.3.0 - 2.2.30 - 2.1.27 + 2.2.32 + 2.1.28 1.19.0 0.7.0 7.1.0 diff --git a/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java b/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java index a8e124a6b8..982eefe1a7 100644 --- a/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java +++ b/apiserver/src/main/java/org/dependencytrack/auth/Permissions.java @@ -61,11 +61,6 @@ public enum Permissions { POLICY_MANAGEMENT_READ("Allows reading of policies"), POLICY_MANAGEMENT_UPDATE("Allows the modification of a policy"), POLICY_MANAGEMENT_DELETE("Allows the deletion of a policy"), - ROLE_MANAGEMENT("Allows the creation, modification, and deletion of roles"), - ROLE_MANAGEMENT_CREATE("Allows the creation of roles"), - ROLE_MANAGEMENT_READ("Allows reading of roles"), - ROLE_MANAGEMENT_UPDATE("Allows update of roles"), - ROLE_MANAGEMENT_DELETE("Allows the deletion of roles"), TAG_MANAGEMENT("Allows the modification and deletion of tags"), TAG_MANAGEMENT_DELETE("Allows the deletion of a tag"), VIEW_BADGES("Provides the ability to view badges"); @@ -116,11 +111,6 @@ public static class Constants { public static final String POLICY_MANAGEMENT_READ = "POLICY_MANAGEMENT_READ"; public static final String POLICY_MANAGEMENT_UPDATE = "POLICY_MANAGEMENT_UPDATE"; public static final String POLICY_MANAGEMENT_DELETE = "POLICY_MANAGEMENT_DELETE"; - public static final String ROLE_MANAGEMENT = "ROLE_MANAGEMENT"; - public static final String ROLE_MANAGEMENT_CREATE = "ROLE_MANAGEMENT_CREATE"; - public static final String ROLE_MANAGEMENT_READ = "ROLE_MANAGEMENT_READ"; - public static final String ROLE_MANAGEMENT_UPDATE = "ROLE_MANAGEMENT_UPDATE"; - public static final String ROLE_MANAGEMENT_DELETE = "ROLE_MANAGEMENT_DELETE"; public static final String TAG_MANAGEMENT = "TAG_MANAGEMENT"; public static final String TAG_MANAGEMENT_DELETE = "TAG_MANAGEMENT_DELETE"; public static final String VIEW_BADGES = "VIEW_BADGES"; diff --git a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java index 2c4d79fbae..05dfccdd99 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java @@ -18,7 +18,6 @@ */ package org.dependencytrack.model; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import alpine.model.User; @@ -57,12 +56,10 @@ public class ProjectRole implements Serializable { @Persistent(defaultFetchGroup = "true") @Column(name = "ROLE_ID", allowsNull = "false") - @JsonIgnore private Role role; @Persistent(defaultFetchGroup = "true") @Column(name = "PROJECT_ID", allowsNull = "false") - @JsonIgnore private Project project; @Persistent(defaultFetchGroup = "true") diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 8f4ca117b3..15ea00f4ef 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -60,14 +60,13 @@ @PersistenceCapable @FetchGroup(name = "ALL", members = { @Persistent(name = "name"), - @Persistent(name = "description"), @Persistent(name = "permissions"), @Persistent(name = "uuid"), }) @JsonInclude(JsonInclude.Include.NON_NULL) public class Role implements Serializable { - private static final long serialVersionUID = -7592438796591673355L; + private static final long serialVersionUID = -427858073810766917L; /** * Defines JDO fetch groups for this class. @@ -90,14 +89,6 @@ public enum FetchGroup { @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, message = "The name may only contain printable characters") private String name; - @Persistent - @Column(name = "DESCRIPTION", jdbcType = "VARCHAR") - @Size(max = 255) - @JsonDeserialize(using = TrimmedStringDeserializer.class) - @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS, - message = "The description may only contain printable characters") - private String description; - @Persistent(table = "ROLES_PERMISSIONS", defaultFetchGroup = "true") @Unique(name = "ROLES_PERMISSIONS_IDX") @Join(column = "ROLE_ID") @@ -160,7 +151,6 @@ public String toString() { id, uuid, name, - description != null ? description : "", permissionStrings); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java index e1a480005a..cdb638f6e7 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java @@ -24,8 +24,10 @@ import alpine.model.ManagedUser; import alpine.model.Permission; import alpine.server.auth.PasswordService; + import jakarta.servlet.ServletContextEvent; import jakarta.servlet.ServletContextListener; + import org.dependencytrack.auth.Permissions; import org.dependencytrack.common.ConfigKey; import org.dependencytrack.model.ConfigPropertyConstants; @@ -38,8 +40,10 @@ import org.dependencytrack.util.WaitingLockConfiguration; import java.io.IOException; + import java.time.Duration; import java.time.Instant; +import java.util.Collections; import java.time.LocalDate; import java.util.HashMap; import java.util.List; @@ -61,7 +65,56 @@ public class DefaultObjectGenerator implements ServletContextListener { private static final Logger LOGGER = Logger.getLogger(DefaultObjectGenerator.class); - private final Map permissionsMap = new HashMap<>(); + private static final Map PERMISSIONS_MAP = new HashMap<>(); + + private static final Map> DEFAULT_TEAM_PERMISSIONS = Map.of( + "Administrators", Stream.of(Permissions.values()) + .map(Permissions::name) + .toList(), + "Portfolio Managers", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.PORTFOLIO_MANAGEMENT, + Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, + Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE), + "Automation", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.BOM_UPLOAD), + "Badge Viewers", List.of( + Permissions.Constants.VIEW_BADGES)); + + private static final Map> DEFAULT_ROLE_PERMISSIONS = Map.of( + "Project Admin", List.of( + Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, + Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE, + Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE, + Permissions.Constants.VULNERABILITY_ANALYSIS, + Permissions.Constants.VULNERABILITY_ANALYSIS_CREATE, + Permissions.Constants.VULNERABILITY_ANALYSIS_READ, + Permissions.Constants.VULNERABILITY_ANALYSIS_UPDATE, + Permissions.Constants.POLICY_MANAGEMENT, + Permissions.Constants.POLICY_MANAGEMENT_CREATE, + Permissions.Constants.POLICY_MANAGEMENT_READ, + Permissions.Constants.POLICY_MANAGEMENT_UPDATE, + Permissions.Constants.POLICY_MANAGEMENT_DELETE), + "Project Auditor", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.VIEW_VULNERABILITY, + Permissions.Constants.VIEW_POLICY_VIOLATION, + Permissions.Constants.VULNERABILITY_ANALYSIS_READ), + "Project Editor", List.of( + Permissions.Constants.BOM_UPLOAD, + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, + Permissions.Constants.VIEW_VULNERABILITY, + Permissions.Constants.VULNERABILITY_ANALYSIS_READ, + Permissions.Constants.PROJECT_CREATION_UPLOAD), + "Project Viewer", List.of( + Permissions.Constants.VIEW_PORTFOLIO, + Permissions.Constants.VIEW_VULNERABILITY, + Permissions.Constants.VIEW_BADGES)); /** * {@inheritDoc} @@ -123,6 +176,7 @@ private void executeLocked() { loadDefaultLicenses(qm); loadDefaultLicenseGroups(qm); loadDefaultRepositories(qm); + loadDefaultRoles(qm); loadDefaultConfigProperties(qm); loadDefaultNotificationPublishers(qm); recordDefaultObjectsVersion(qm); @@ -216,23 +270,16 @@ public void loadDefaultPermissions() { private void loadDefaultPermissions(final QueryManager qm) { LOGGER.info("Synchronizing permissions to datastore"); - for (final Permissions permission : Permissions.values()) { - if (qm.getPermission(permission.name()) == null) { - LOGGER.debug("Creating permission: " + permission.name()); - permissionsMap.put(permission.name(), - qm.createPermission(permission.name(), permission.getDescription())); - } - } - } - - private void createTeam(final QueryManager qm, final String name, final List permissions) { - LOGGER.debug("Creating team: " + name); - var team = qm.createTeam(name); - - LOGGER.debug("Assigning default permissions for team: " + name); - team.setPermissions(permissions); + List existing = Objects.requireNonNullElse(qm.getPermissions(), Collections.emptyList()) + .stream() + .map(Permission::getName) + .toList(); - qm.persist(team); + for (final Permissions value : Permissions.values()) + if (!existing.contains(value.name())) { + LOGGER.debug("Creating permission: " + value.name()); + PERMISSIONS_MAP.put(value.name(), qm.createPermission(value.name(), value.getDescription())); + } } @SuppressWarnings("unused") @@ -250,14 +297,20 @@ private void loadDefaultPersonas(final QueryManager qm) { return; LOGGER.info("Adding default users and teams to datastore"); + LOGGER.debug("Creating user: admin"); ManagedUser admin = qm.createManagedUser("admin", "Administrator", "admin@localhost", new String(PasswordService.createHash("admin".toCharArray())), true, true, false); - createTeam(qm, "Administrators", List.copyOf(permissionsMap.values())); - createTeam(qm, "Portfolio Managers", getPortfolioManagersPermissions()); - createTeam(qm, "Automation", getAutomationPermissions()); - createTeam(qm, "Badge Viewers", getBadgesPermissions()); + for (var name : new String[] { "Administrators", "Portfolio Managers", "Automation", "Badge Viewers" }) { + LOGGER.debug("Creating team: " + name); + var team = qm.createTeam(name); + + LOGGER.debug("Assigning default permissions for team: " + name); + team.setPermissions(getPermissionsByName(DEFAULT_TEAM_PERMISSIONS.get(name))); + + qm.persist(team); + } LOGGER.debug("Adding admin user to System Administrators"); qm.addUserToTeam(admin, qm.getTeam("Administrators")); @@ -267,35 +320,35 @@ private void loadDefaultPersonas(final QueryManager qm) { qm.persist(admin); } - private List getPortfolioManagersPermissions() { - return getPermissionsByName(Permissions.Constants.VIEW_PORTFOLIO, - Permissions.Constants.PORTFOLIO_MANAGEMENT, - Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE, - Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, - Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE, - Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE); - } - - private List getAutomationPermissions() { - return getPermissionsByName(Permissions.Constants.VIEW_PORTFOLIO, - Permissions.Constants.BOM_UPLOAD); - } - - private List getBadgesPermissions() { - return getPermissionsByName(Permissions.Constants.VIEW_BADGES); - } - /** * Perform a lookup of {@link Permission}s for specified name(s). * * @param names permission names * @return list of {@link Permission}s */ - private List getPermissionsByName(String... names) { - return Stream.of(names) - .map(permissionsMap::get) - .filter(Objects::nonNull) - .toList(); + private List getPermissionsByName(List names) { + return names.stream().map(PERMISSIONS_MAP::get).filter(Objects::nonNull).toList(); + } + + public void loadDefaultRoles() { + try (final var qm = new QueryManager()) { + loadDefaultRoles(qm); + } + } + + /** + * Loads the default Roles + */ + private void loadDefaultRoles(final QueryManager qm) { + if (!qm.getRoles().isEmpty()) + return; + + LOGGER.info("Adding default roles to datastore"); + + for (var name : new String[] { "Project Admin", "Project Auditor", "Project Editor", "Project Viewer" }) { + LOGGER.debug("Creating role: " + name); + qm.createRole(name, getPermissionsByName(DEFAULT_ROLE_PERMISSIONS.get(name))); + } } public void loadDefaultRepositories() { diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java index 5028f2db6d..36605d37ff 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java @@ -1021,31 +1021,23 @@ public void bind(final Project project, final Collection tags) { @Override public boolean hasAccess(final Principal principal, final Project project) { - if (principal == null) { - // This is a system request being made (e.g. MetricsUpdateTask, etc) where there isn't a principal + if (!isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED) + || principal == null // System request (e.g. MetricsUpdateTask, etc) where there isn't a principal + || super.hasAccessManagementPermission(principal)) // TODO: After Alpine >= 3.2.0: request.getEffectivePermission().contains(Permissions.ACCESS_MANAGEMENT.name()) return true; - } - - if (!isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED)) { - return true; - } - - // TODO: After upgrading to Alpine >= 3.2.0, this should become: - // request.getEffectivePermission().contains(Permissions.ACCESS_MANAGEMENT.name()) - // https://github.com/stevespringett/Alpine/pull/764 - if (super.hasAccessManagementPermission(principal)) { - return true; - } + final Set roleIds = getRoleIds(principal, project); final Set teamIds = getTeamIds(principal); - if (teamIds.isEmpty()) { + + if (teamIds.isEmpty() && roleIds.isEmpty()) return false; - } - final Query query = pm.newQuery(Query.SQL, "SELECT HAS_PROJECT_ACCESS(:projectId, :teamIds)"); + final Query query = pm.newQuery(Query.SQL, "SELECT HAS_PROJECT_ACCESS(:projectId, :teamIds, :roleIds)"); query.setNamedParameters(Map.ofEntries( Map.entry("projectId", project.getId()), - Map.entry("teamIds", teamIds.toArray(new Long[0])))); + Map.entry("teamIds", teamIds.toArray(Long[]::new)), + Map.entry("roleIds", roleIds.toArray(Long[]::new)))); + return executeAndCloseResultUnique(query, Boolean.class); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 03ae382ecf..4b58deb11c 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -23,9 +23,6 @@ import alpine.common.validation.RegexSequence; import alpine.model.ApiKey; import alpine.model.ConfigProperty; -import alpine.model.LdapUser; -import alpine.model.ManagedUser; -import alpine.model.OidcUser; import alpine.model.IConfigProperty.PropertyType; import alpine.model.Permission; import alpine.model.Team; @@ -70,9 +67,11 @@ import org.dependencytrack.model.PolicyViolation; import org.dependencytrack.model.Project; import org.dependencytrack.model.ProjectProperty; +import org.dependencytrack.model.ProjectRole; import org.dependencytrack.model.Repository; import org.dependencytrack.model.RepositoryMetaComponent; import org.dependencytrack.model.RepositoryType; +import org.dependencytrack.model.Role; import org.dependencytrack.model.ServiceComponent; import org.dependencytrack.model.Tag; import org.dependencytrack.model.Vex; @@ -117,7 +116,6 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -150,6 +148,7 @@ public class QueryManager extends AlpineQueryManager { private PolicyQueryManager policyQueryManager; private ProjectQueryManager projectQueryManager; private RepositoryQueryManager repositoryQueryManager; + private RoleQueryManager roleQueryManager; private ServiceComponentQueryManager serviceComponentQueryManager; private VexQueryManager vexQueryManager; private VulnerabilityQueryManager vulnerabilityQueryManager; @@ -428,6 +427,13 @@ private RepositoryQueryManager getRepositoryQueryManager() { return repositoryQueryManager; } + private RoleQueryManager getRoleQueryManager(){ + if (roleQueryManager == null) { + roleQueryManager = (request ==null) ? new RoleQueryManager(getPersistenceManager()) : new RoleQueryManager(getPersistenceManager(), request); + } + return roleQueryManager; + } + /** * Lazy instantiation of NotificationQueryManager. * @@ -860,11 +866,11 @@ public void deletePolicyCondition(PolicyCondition policyCondition) { getPolicyQueryManager().deletePolicyCondition(policyCondition); } - public Role createRole(Role role) { - return getRoleQueryManager().createRole(role); + public Role createRole(final String name, final List permissions) { + return getRoleQueryManager().createRole(name, permissions); } - public List getRoles() { + public List getRoles() { return getRoleQueryManager().getRoles(); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index fb891009ac..fbc5c7a247 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -1,12 +1,37 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ package org.dependencytrack.persistence; -import java.nio.file.attribute.UserPrincipal; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import javax.jdo.PersistenceManager; +import javax.jdo.Query; +import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; +import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.persistence.jdbi.JdbiFactory; +import org.dependencytrack.persistence.jdbi.RoleDao; import org.apache.commons.lang3.StringUtils; @@ -20,7 +45,21 @@ final class RoleQueryManager extends QueryManager implements IQueryManager { - private static final Logger LOGGER = Logger.getLogger(ProjectQueryManager.class); + /** + * Represents a row returned by the USER_PROJECT_EFFECTIVE_PERMISSIONS view. + * + * @since 5.6.0 + */ + public record UserProjectEffectivePermissionsRow( + Long ldapUserId, + Long managedUserId, + Long oidcUserId, + Long projectId, + Long permissionId, + String permissionName) { + } + + private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); RoleQueryManager(final PersistenceManager pm) { super(pm); @@ -30,14 +69,24 @@ final class RoleQueryManager extends QueryManager implements IQueryManager { super(pm, request); } - public Role createRole(Role role) { - // TODO:Implement role creation logic - return role; + @Override + public Role createRole(final String name, final List permissions) { + return callInTransaction(() -> { + final Role role = new Role(); + role.setName(name); + role.setPermissions(Set.copyOf(permissions)); + + return persist(role); + }); } + @Override public List getRoles() { - // TODO:Implement role retrieval logic - return Collections.emptyList(); + final Query query = pm.newQuery(Role.class); + if (orderBy == null) + query.setOrdering("name asc"); + + return query.executeList(); } @Override diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java index 0af0eb5ec5..8a5e353a27 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -18,6 +18,14 @@ */ package org.dependencytrack.persistence.jdbi; +import java.util.List; + +import org.dependencytrack.model.Project; +import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.persistence.jdbi.mapping.ProjectRoleRowMapper; + +import org.jdbi.v3.sqlobject.config.RegisterFieldMapper; +import org.jdbi.v3.sqlobject.config.RegisterRowMapper; import org.jdbi.v3.sqlobject.customizer.Bind; import org.jdbi.v3.sqlobject.statement.SqlQuery; import org.jdbi.v3.sqlobject.statement.SqlUpdate; @@ -48,7 +56,8 @@ public interface RoleDao { ("USER_ID", "PROJECT_ID", "ROLE_ID") VALUES (:userId, :projectId, :roleId) - ON CONFLICT DO NOTHING + ON CONFLICT ("USER_ID", "PROJECT_ID") DO + UPDATE SET "ROLE_ID" = EXCLUDED."ROLE_ID" """) int addRoleToUser(@Bind long userId, @Bind long projectId, @Bind long roleId); @@ -112,13 +121,4 @@ SELECT EXISTS ( @RegisterFieldMapper(Project.class) List getUserUnassignedProjects(@Bind String username); - @SqlUpdate(/* language=sql */ """ - INSERT INTO "USERS_PROJECTS_ROLES" - ("USER_ID", "PROJECT_ID", "ROLE_ID") - VALUES (:userId, (SELECT "ID" FROM "PROJECT" WHERE "NAME" = :projectName), :roleId) - ON CONFLICT ("USER_ID", "PROJECT_ID") DO - UPDATE SET "ROLE_ID" = EXCLUDED."ROLE_ID" - """) - int setUserProjectRole(@Bind long userId, @Bind String projectName, @Bind long roleId); - } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java index f784e1ad8e..d6bc2047c9 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java @@ -29,8 +29,10 @@ import org.jdbi.v3.core.mapper.RowMapper; import org.jdbi.v3.core.statement.StatementContext; + import java.sql.ResultSet; import java.sql.SQLException; +import java.util.UUID; import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.maybeSet; @@ -62,10 +64,10 @@ public ProjectRole map(final ResultSet resultSet, final StatementContext ctx) th projectRole.getProject().setUuid(UUID.fromString(value)); }); - maybeSet(resultSet, "ROLE_ID", ResultSet::getLong, value -> { - var role = new Role(); - role.setId(value); - projectRole.setRole(role); + maybeSet(resultSet, "ROLE_ID", ResultSet::getLong, projectRole.getRole()::setId); + maybeSet(resultSet, "ROLE_NAME", ResultSet::getString, projectRole.getRole()::setName); + maybeSet(resultSet, "ROLE_UUID", ResultSet::getString, value -> { + projectRole.getRole().setUuid(UUID.fromString(value)); }); return projectRole; diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java new file mode 100644 index 0000000000..ba435afed2 --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java @@ -0,0 +1,88 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.persistence.jdbi.mapping; + +import org.cyclonedx.model.ExternalReference; +import org.dependencytrack.model.Classifier; +import org.dependencytrack.model.Project; +import org.dependencytrack.persistence.converter.OrganizationalContactsJsonConverter; +import org.dependencytrack.persistence.converter.OrganizationalEntityJsonConverter; +import org.jdbi.v3.core.mapper.RowMapper; +import org.jdbi.v3.core.statement.StatementContext; + +import com.fasterxml.jackson.core.type.TypeReference; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.UUID; + +import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.deserializeJson; +import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.maybeSet; + +public class ProjectRowMapper implements RowMapper { + + private static final TypeReference> EXTERNAL_REFS_TYPE_REF = new TypeReference<>() { + }; + + @Override + public Project map(final ResultSet rs, final StatementContext ctx) throws SQLException { + final var project = new Project(); + + maybeSet(rs, "ID", ResultSet::getLong, project::setId); + maybeSet(rs, "CLASSIFIER", ResultSet::getString, Classifier::valueOf); + maybeSet(rs, "CPE", ResultSet::getString, project::setCpe); + maybeSet(rs, "DESCRIPTION", ResultSet::getString, project::setDescription); + maybeSet(rs, "DIRECT_DEPENDENCIES", ResultSet::getString, project::setDirectDependencies); + deserializeJson(rs, "EXTERNAL_REFERENCES", EXTERNAL_REFS_TYPE_REF); + maybeSet(rs, "GROUP", ResultSet::getString, project::setGroup); + maybeSet(rs, "LAST_BOM_IMPORTED", ResultSet::getDate, project::setLastBomImport); + maybeSet(rs, "LAST_BOM_IMPORTED_FORMAT", ResultSet::getString, project::setLastBomImportFormat); + maybeSet(rs, "LAST_RISKSCORE", ResultSet::getDouble, project::setLastInheritedRiskScore); + maybeSet(rs, "NAME", ResultSet::getString, project::setName); + maybeSet(rs, "PARENT_PROJECT_ID", ResultSet::getLong, value -> { + var parent = new Project(); + parent.setId(value); + project.setParent(parent); + }); + maybeSet(rs, "PUBLISHER", ResultSet::getString, project::setPublisher); + maybeSet(rs, "PURL", ResultSet::getString, project::setPurl); + maybeSet(rs, "SWIDTAGID", ResultSet::getString, project::setSwidTagId); + maybeSet(rs, "UUID", ResultSet::getString, value -> { + var uuid = UUID.fromString(value); + project.setUuid(uuid); + }); + maybeSet(rs, "VERSION", ResultSet::getString, project::setVersion); + maybeSet(rs, "SUPPLIER", ResultSet::getString, value -> { + var converter = new OrganizationalEntityJsonConverter(); + project.setSupplier(converter.convertToAttribute(value)); + }); + maybeSet(rs, "MANUFACTURER", ResultSet::getString, value -> { + var converter = new OrganizationalEntityJsonConverter(); + project.setManufacturer(converter.convertToAttribute(value)); + }); + maybeSet(rs, "AUTHORS", ResultSet::getString, values -> { + var converter = new OrganizationalContactsJsonConverter(); + project.setAuthors(converter.convertToAttribute(values)); + }); + + return project; + } + +} \ No newline at end of file diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index 3319b31f9a..a9cda5498b 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -20,6 +20,7 @@ import alpine.common.logging.Logger; import alpine.model.Team; +import alpine.model.User; import alpine.persistence.PaginatedResult; import alpine.server.auth.PermissionRequired; import alpine.server.resources.AlpineResource; @@ -58,7 +59,6 @@ import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; -import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java index d2d6b3337b..d85b5f6bd5 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java @@ -34,6 +34,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirements; import io.swagger.v3.oas.annotations.tags.Tag; import org.dependencytrack.auth.Permissions; +import org.dependencytrack.model.Role; import org.dependencytrack.model.validation.ValidUuid; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.resources.v1.vo.TeamPermissionsSetRequest; @@ -54,6 +55,7 @@ import javax.jdo.Query; import java.util.List; import java.util.Map; +import java.util.Set; /** * JAX-RS resources for processing permissions. @@ -227,6 +229,94 @@ public Response addPermissionToTeam( } } + @DELETE + @Path("/{permission}/role/{uuid}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "The updated role", + content = @Content(schema = @Schema(implementation = Role.class)) + ), + @ApiResponse(responseCode = "304", description = "The role already has the specified permission assigned"), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The role could not be found") + }) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) + public Response removePermissionFromRole( + @Parameter(description = "A valid role uuid", schema = @Schema(type = "string", format = "uuid"), required = true) + @PathParam("uuid") @ValidUuid String uuid, + @Parameter(description = "A valid permission", required = true) + @PathParam("permission") String permissionName) { + try (QueryManager qm = new QueryManager()) { + Role role = qm.getObjectByUuid(Role.class, uuid); + if (role == null) { + return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + } + final Permission permission = qm.getPermission(permissionName); + if (permission == null) { + return Response.status(Response.Status.NOT_FOUND).entity("The permission could not be found.").build(); + } + final Set permissions = role.getPermissions(); + if (permissions != null && permissions.contains(permission)) { + permissions.remove(permission); + role.setPermissions(permissions); + role = qm.persist(role); + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Removed permission for role: " + role.getName() + " / permission: " + permission.getName()); + return Response.ok(role).build(); + } + return Response.status(Response.Status.NOT_MODIFIED).build(); + } + } + + @POST + @Path("/{permission}/role/{uuid}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation( + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "The updated role", + content = @Content(schema = @Schema(implementation = Role.class)) + ), + @ApiResponse(responseCode = "304", description = "The role already has the specified permission assigned"), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The role could not be found") + }) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) + public Response addPermissionToRole( + @Parameter(description = "A valid role uuid", schema = @Schema(type = "string", format = "uuid"), required = true) + @PathParam("uuid") @ValidUuid String uuid, + @Parameter(description = "A valid permission", required = true) + @PathParam("permission") String permissionName) { + try (QueryManager qm = new QueryManager()) { + Role role = qm.getObjectByUuid(Role.class, uuid); + if (role == null) { + return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); + } + final Permission permission = qm.getPermission(permissionName); + if (permission == null) { + return Response.status(Response.Status.NOT_FOUND).entity("The permission could not be found.").build(); + } + final Set permissions = role.getPermissions(); + if (permissions != null && !permissions.contains(permission)) { + permissions.add(permission); + role.setPermissions(permissions); + role = qm.persist(role); + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added permission for role: " + role.getName() + " / permission: " + permission.getName()); + return Response.ok(role).build(); + } + return Response.status(Response.Status.NOT_MODIFIED).build(); + } + } + @DELETE @Path("/{permission}/team/{uuid}") @Consumes(MediaType.APPLICATION_JSON) @@ -251,7 +341,7 @@ public Response removePermissionFromTeam( @Parameter(description = "A valid permission", required = true) @PathParam("permission") String permissionName) { try (QueryManager qm = new QueryManager()) { - Team team = qm.getObjectByUuid(Team.class, uuid); + Team team = qm.getObjectByUuid(Team.class, uuid, Team.FetchGroup.ALL.name()); if (team == null) { return Response.status(Response.Status.NOT_FOUND).entity("The team could not be found.").build(); } @@ -275,7 +365,10 @@ public Response removePermissionFromTeam( @Path("/user") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") + @Operation( + summary = "Replaces a users's permissions with the specified list", + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" + ) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "The updated user", content = @Content(schema = @Schema(implementation = User.class))), @ApiResponse(responseCode = "304", description = "The user is already has the specified permission(s)"), @@ -284,7 +377,8 @@ public Response removePermissionFromTeam( @ApiResponse(responseCode = "404", description = "The user could not be found") }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) - public Response setUserPermissions(@Parameter(description = "A username and valid list permission") @Valid UserPermissionsSetRequest request) { + public Response setUserPermissions( + @Parameter(description = "A username and valid list permission") @Valid UserPermissionsSetRequest request) { try (QueryManager qm = new QueryManager()) { User user = qm.getUser(request.username()); if (user == null) @@ -316,7 +410,7 @@ public Response setUserPermissions(@Parameter(description = "A username and vali user = qm.persist(user); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Set permissions for user: %s / permissions: %s" - .formatted(user.getName(), permissionNames)); + .formatted(user.getUsername(), permissionNames)); return Response.ok(user).build(); } @@ -326,7 +420,10 @@ public Response setUserPermissions(@Parameter(description = "A username and vali @Path("/team") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Operation(description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") + @Operation( + summary = "Replaces a team's permissions with the specified list", + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" + ) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "The updated team", content = @Content(schema = @Schema(implementation = Team.class))), @ApiResponse(responseCode = "304", description = "The team already has the specified permission(s)"), @@ -337,7 +434,7 @@ public Response setUserPermissions(@Parameter(description = "A username and vali @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response setTeamPermissions(@Parameter(description = "Team UUID and requested permissions") @Valid TeamPermissionsSetRequest request) { try (QueryManager qm = new QueryManager()) { - Team team = qm.getObjectByUuid(Team.class, request.team()); + Team team = qm.getObjectByUuid(Team.class, request.team(), Team.FetchGroup.ALL.name()); if (team == null) return Response.status(Response.Status.NOT_FOUND).entity("The team could not be found.").build(); @@ -362,7 +459,7 @@ public Response setTeamPermissions(@Parameter(description = "Team UUID and reque return Response.notModified().entity("Team already has selected permission(s).").build(); team.setPermissions(requestedPermissions); - qm.persist(team); + team = qm.persist(team); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Set permissions for team: %s / permissions: %s" diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index 80736b1524..a639cbf4fc 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -19,9 +19,6 @@ package org.dependencytrack.resources.v1; import alpine.common.logging.Logger; -import alpine.model.Permission; -import alpine.model.Role; -import alpine.model.UserPrincipal; import alpine.server.auth.PermissionRequired; import alpine.server.resources.AlpineResource; @@ -50,6 +47,8 @@ import org.dependencytrack.auth.Permissions; import org.dependencytrack.model.validation.ValidUuid; +import org.dependencytrack.model.Role; +import org.dependencytrack.model.ProjectRole; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.persistence.jdbi.RoleDao; import org.dependencytrack.resources.v1.vo.CreateRoleRequest; @@ -87,7 +86,7 @@ public class RoleResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all roles", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

") + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

") @ApiResponses(value = { @ApiResponse( responseCode = "200", @@ -99,7 +98,7 @@ public class RoleResource extends AlpineResource { content = @Content(array = @ArraySchema(schema = @Schema(implementation = Role.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_READ}) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ }) public Response getRoles() { try (QueryManager qm = new QueryManager()) { return Response.ok(qm.getRoles()).header(TOTAL_COUNT_HEADER, qm.getCount(Role.class)).build(); @@ -111,7 +110,7 @@ public Response getRoles() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a specific role", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_READ

") + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

") @ApiResponses(value = { @ApiResponse( responseCode = "200", @@ -120,7 +119,7 @@ public Response getRoles() { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) - @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_READ}) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ }) public Response getRole( @Parameter( description = "The UUID of the role to retrieve", @@ -138,13 +137,15 @@ public Response getRole( @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Operation(summary = "Creates a new role", description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_CREATE

") + @Operation( + summary = "Creates a new role", + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "The created role", content = @Content(schema = @Schema(implementation = Role.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "The Role already exists"), }) - @PermissionRequired({ Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_CREATE }) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE }) public Response createRole(@Valid CreateRoleRequest request) { try (QueryManager qm = new QueryManager()) { boolean roleExists = qm.getRoleByName(request.name()) != null; @@ -184,7 +185,7 @@ public Response createRole(@Valid CreateRoleRequest request) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a role's fields", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_UPDATE

") + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") @ApiResponses(value = { @ApiResponse( responseCode = "200", @@ -193,7 +194,7 @@ public Response createRole(@Valid CreateRoleRequest request) { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) - @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_UPDATE}) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response updateRole(Role jsonRole) { failOnValidationError(super.getValidator().validateProperty(jsonRole, "name")); @@ -213,13 +214,13 @@ public Response updateRole(Role jsonRole) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a role", - description = "

Requires permission ROLE_MANAGEMENT or ROLE_MANAGEMENT_DELETE

") + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

") @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "Role removed successfully"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) - @PermissionRequired({Permissions.Constants.ROLE_MANAGEMENT, Permissions.Constants.ROLE_MANAGEMENT_DELETE}) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE }) public Response deleteRole(Role jsonRole) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, jsonRole.getUuid(), Role.FetchGroup.ALL.name()); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/TeamResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/TeamResource.java index d262f682be..3215200c1a 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/TeamResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/TeamResource.java @@ -125,7 +125,7 @@ public Response getTeam( @Parameter(description = "The UUID of the team to retrieve", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { try (QueryManager qm = new QueryManager()) { - final Team team = qm.getObjectByUuid(Team.class, uuid); + final Team team = qm.getObjectByUuid(Team.class, uuid, Team.FetchGroup.ALL.name()); if (team != null) { return Response.ok(team).build(); } else { diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 9adbfd6a96..8e489d59b9 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -52,6 +52,8 @@ import org.dependencytrack.auth.Permissions; import org.dependencytrack.event.kafka.KafkaEventDispatcher; import org.dependencytrack.model.IdentifiableObject; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Role; import org.dependencytrack.notification.NotificationConstants; import org.dependencytrack.notification.NotificationGroup; import org.dependencytrack.notification.NotificationScope; @@ -59,6 +61,7 @@ import org.dependencytrack.proto.notification.v1.UserSubject; import org.dependencytrack.resources.v1.problems.AccessManagementProblemDetails; import org.dependencytrack.resources.v1.problems.ProblemDetails; +import org.dependencytrack.resources.v1.vo.RoleProjectRequest; import org.dependencytrack.resources.v1.vo.TeamsSetRequest; import org.owasp.security.logging.SecurityMarkers; @@ -169,7 +172,7 @@ public Response validateCredentials(@FormParam("username") String username, @For @AuthenticationNotRequired public Response validateOidcAccessToken(@Parameter(description = "An OAuth2 access token", required = true) @FormParam("idToken") final String idToken, - @FormParam("accessToken") final String accessToken) { + @FormParam("accessToken") final String accessToken) { final OidcAuthenticationService authService = new OidcAuthenticationService(idToken, accessToken); if (!authService.isSpecified()) { @@ -903,7 +906,6 @@ public Response assignProjectRoleToUser( qm.addRoleToUser(user, role, project); - principal = qm.getObjectById(principal.getClass(), principal.getId()); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Granted project role: user='%s', role='%s', project='%s'" .formatted(user.getUsername(), role.getName(), project.getName())); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/CreateRoleRequest.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/CreateRoleRequest.java new file mode 100644 index 0000000000..fb8c89f981 --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/CreateRoleRequest.java @@ -0,0 +1,47 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ + +package org.dependencytrack.resources.v1.vo; + +import java.util.Set; + +import org.dependencytrack.auth.Permissions; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import alpine.common.validation.RegexSequence; +import alpine.server.json.TrimmedStringDeserializer; + +import io.swagger.v3.oas.annotations.media.Schema; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; + +public record CreateRoleRequest( + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + @NotBlank + @JsonDeserialize(using = TrimmedStringDeserializer.class) + @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS_PLUS, message = "The username may only contain printable characters") + String name, + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull + Set permissions) { +} diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java new file mode 100644 index 0000000000..2b31e7fbe8 --- /dev/null +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java @@ -0,0 +1,47 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ +package org.dependencytrack.resources.v1.vo; + +import org.dependencytrack.model.validation.ValidUuid; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +import alpine.common.validation.RegexSequence; +import alpine.server.json.TrimmedStringDeserializer; + +import io.swagger.v3.oas.annotations.media.Schema; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; + +public record RoleProjectRequest( + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + @JsonDeserialize(using = TrimmedStringDeserializer.class) + @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS_PLUS, message = "The username may only contain printable characters") + @NotBlank + String username, + + @ValidUuid + @NotBlank + String role, + + @ValidUuid + @NotBlank + String project) { +} diff --git a/apiserver/src/main/resources/META-INF/persistence.xml b/apiserver/src/main/resources/META-INF/persistence.xml index 0a77577e77..ceebdf4bd6 100644 --- a/apiserver/src/main/resources/META-INF/persistence.xml +++ b/apiserver/src/main/resources/META-INF/persistence.xml @@ -42,6 +42,8 @@ org.dependencytrack.model.ComponentProperty org.dependencytrack.model.Epss org.dependencytrack.model.FindingAttribution + org.dependencytrack.model.IntegrityAnalysis + org.dependencytrack.model.IntegrityMetaComponent org.dependencytrack.model.License org.dependencytrack.model.LicenseGroup org.dependencytrack.model.NotificationPublisher @@ -55,6 +57,7 @@ org.dependencytrack.model.ProjectRole org.dependencytrack.model.Repository org.dependencytrack.model.RepositoryMetaComponent + org.dependencytrack.model.Role org.dependencytrack.model.ServiceComponent org.dependencytrack.model.Tag org.dependencytrack.model.Vex @@ -64,11 +67,10 @@ org.dependencytrack.model.Vulnerability org.dependencytrack.model.VulnerabilityAlias org.dependencytrack.model.VulnerabilityMetrics + org.dependencytrack.model.VulnerabilityPolicyBundle org.dependencytrack.model.VulnerabilityScan org.dependencytrack.model.VulnerableSoftware org.dependencytrack.model.WorkflowState - org.dependencytrack.model.IntegrityAnalysis - org.dependencytrack.model.VulnerabilityPolicyBundle true NONE diff --git a/apiserver/src/test/java/org/dependencytrack/ResourceTest.java b/apiserver/src/test/java/org/dependencytrack/ResourceTest.java index 204af31684..147e4a5b43 100644 --- a/apiserver/src/test/java/org/dependencytrack/ResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/ResourceTest.java @@ -73,6 +73,7 @@ public abstract class ResourceTest { protected final String V1_PROJECT = "/v1/project"; protected final String V1_PROJECT_LATEST = "/v1/project/latest/"; protected final String V1_REPOSITORY = "/v1/repository"; + protected final String V1_ROLE = "/v1/role"; protected final String V1_SCAN = "/v1/scan"; protected final String V1_SEARCH = "/v1/search"; protected final String V1_TEAM = "/v1/team"; diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java index 255b597c09..3136116c4e 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/NotificationRuleResourceTest.java @@ -502,7 +502,8 @@ public void addTeamToRuleWithCustomEmailPublisherTest() { "teams": [ { "uuid": "${json-unit.matches:teamUuid}", - "name": "Team Example" + "name": "Team Example", + "permissions": [] } ], "notifyOn": [], diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java index bc8c2960cd..9677001edb 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java @@ -253,7 +253,7 @@ public void removePermissionFromTeamTest() { JsonObject json = parseJsonObject(response); Assert.assertNotNull(json); Assert.assertEquals("team1", json.getString("name")); - Assert.assertFalse(json.containsKey("permissions")); + Assert.assertEquals(0, json.getJsonArray("permissions").size()); } @Test diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java index a633977105..9caf04ed61 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/TeamResourceTest.java @@ -156,7 +156,7 @@ public void createTeamTest() { Assert.assertNotNull(json); Assert.assertEquals("My Team", json.getString("name")); Assert.assertTrue(UuidUtil.isValidUUID(json.getString("uuid"))); - Assert.assertFalse(json.containsKey("apiKeys")); + Assert.assertEquals(0, json.getJsonArray("apiKeys").size()); } @Test diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java index 810f1393ac..afadc885a6 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java @@ -30,7 +30,10 @@ import org.dependencytrack.ResourceTest; import org.dependencytrack.event.kafka.KafkaTopics; import org.dependencytrack.model.IdentifiableObject; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Role; import org.dependencytrack.notification.NotificationConstants; +import org.dependencytrack.resources.v1.vo.RoleProjectRequest; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; @@ -749,4 +752,104 @@ public void setUserTeamsInvalidTest() { Assert.assertEquals(404, response.getStatus()); } + + @Test + public void assignProjectRoleToUserTest() { + // Arrange + ManagedUser user = qm.createManagedUser("roleuser", TEST_USER_PASSWORD_HASH); + Project project = qm.createProject( + "Test Project", "null", + "null", Collections.emptyList(), + null, null, null, false); + + Role role = qm.createRole("Test Role", Collections.emptyList()); + + RoleProjectRequest request = new RoleProjectRequest( + user.getUsername(), + role.getUuid().toString(), + project.getUuid().toString()); + + // Act + Response response = jersey.target(V1_USER + "/role").request() + .header(X_API_KEY, apiKey) + .put(Entity.entity(request, MediaType.APPLICATION_JSON)); + + // Assert + Assert.assertEquals(200, response.getStatus()); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("roleuser", json.getString("username")); + // Optionally, check if the user has the role for the project in the DB + } + + @Test + public void assignProjectRoleToUserAlreadyAssignedTest() { + ManagedUser user = qm.createManagedUser("roleuser2", TEST_USER_PASSWORD_HASH); + Project project = qm.createProject( + "Test Project 2","null", + "null",Collections.emptyList(), + null,null,null,false); + Role role = qm.createRole("Test Role 2", Collections.emptyList()); + qm.addRoleToUser(user, role, project); + + + RoleProjectRequest request = new RoleProjectRequest( + user.getUsername(), + role.getUuid().toString(), + project.getUuid().toString() + ); + + Response response = jersey.target(V1_USER + "/role").request() + .header(X_API_KEY, apiKey) + .put(Entity.entity(request, MediaType.APPLICATION_JSON)); + + Assert.assertEquals(304, response.getStatus()); + } + + @Test + public void removeProjectRoleFromUserTest() { + ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); + Project project = qm.createProject( + "Test Project 3","null", + "null",Collections.emptyList(), + null,null,null,false); + Role role = qm.createRole("Test Role 3", Collections.emptyList()); + qm.addRoleToUser(user, role, project); + + RoleProjectRequest request = new RoleProjectRequest( + user.getUsername(), + role.getUuid().toString(), + project.getUuid().toString() + ); + + Response response = jersey.target(V1_USER + "/role").request() + .header(X_API_KEY, apiKey) + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) + .method("DELETE", Entity.entity(request, MediaType.APPLICATION_JSON)); + + Assert.assertEquals(204, response.getStatus()); + } + + @Test + public void removeProjectRoleFromUserNotAssignedTest() { + ManagedUser user = qm.createManagedUser("roleuser4", TEST_USER_PASSWORD_HASH); + Project project = qm.createProject( + "Test Project 4","null", + "null",Collections.emptyList(), + null,null,null,false); + Role role = qm.createRole("Test Role 4", Collections.emptyList()); + + RoleProjectRequest request = new RoleProjectRequest( + user.getUsername(), + role.getUuid().toString(), + project.getUuid().toString() + ); + + Response response = jersey.target(V1_USER + "/role").request() + .header(X_API_KEY, apiKey) + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) + .method("DELETE", Entity.entity(request, MediaType.APPLICATION_JSON)); + + Assert.assertEquals(304, response.getStatus()); + } } diff --git a/persistence-jooq/pom.xml b/persistence-jooq/pom.xml index b657ad7a4a..8b830a97ba 100644 --- a/persistence-jooq/pom.xml +++ b/persistence-jooq/pom.xml @@ -24,8 +24,8 @@ | IDENTITY | IMPACT | INCLUDING | INFO | INSTALLED | IS | KEYS? | LAST | LDAP | LIBRE | LICENSE | LIKELIHOOD | MANAGED | MAPPED | METRICS | NAME | NOTIFICATION | OCCURRENCE | OIDC | OPERATIONAL | OSI | OWASP | PARENT | PATCHED | PERMISSIONS? | POLICY - | PORTFOLIO | PROJECTS? | PROPERTY | PUBLISHER | PURL | REQUIRED | RISK | RR | RULE - | SCAN | SCHEMA | SCORE | SECURITY | SEE | SERVICE | SOFTWARE | START | STATE + | PORTFOLIO | PROJECTS? | PROPERTY | PUBLISHER | PURL | REQUIRED | RISK | ROLES? | RR + | RULE | SCAN | SCHEMA | SCORE | SECURITY | SEE | SERVICE | SOFTWARE | START | STATE | SUBSCRIBER | SW | SWID | TAGS? | TARGET | TEAMS? | TECHNICAL | TOTAL | TYPE | UNAUDITED | UPGRADES | USER(?!NAME)S? | V2 | V3 | VALUE | VECTOR | VERSIONS? | VIOLATIONS? | VULN | VULNERABILITIES | VULNERABILITY | VULNERABLE | WARN | WEIGHT diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java index 75bb623056..dcd69db81e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java @@ -52,6 +52,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.ProjectsTags; import org.dependencytrack.persistence.jooq.generated.tables.Repository; import org.dependencytrack.persistence.jooq.generated.tables.RepositoryMetaComponent; +import org.dependencytrack.persistence.jooq.generated.tables.Role; +import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponent; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponentsVulnerabilities; import org.dependencytrack.persistence.jooq.generated.tables.Tag; @@ -60,6 +62,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -87,14 +90,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class DefaultSchema extends SchemaImpl { - private static final long serialVersionUID = -158270209; + private static final long serialVersionUID = -1575785433; /** * The reference instance of DEFAULT_SCHEMA @@ -316,6 +319,16 @@ public class DefaultSchema extends SchemaImpl { */ public final RepositoryMetaComponent REPOSITORY_META_COMPONENT = RepositoryMetaComponent.REPOSITORY_META_COMPONENT; + /** + * The table ROLE. + */ + public final Role ROLE = Role.ROLE; + + /** + * The table ROLES_PERMISSIONS. + */ + public final RolesPermissions ROLES_PERMISSIONS = RolesPermissions.ROLES_PERMISSIONS; + /** * The table SERVICECOMPONENT. */ @@ -356,6 +369,11 @@ public class DefaultSchema extends SchemaImpl { */ public final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; + /** + * The table USERS_PROJECTS_ROLES. + */ + public final UsersProjectsRoles USERS_PROJECTS_ROLES = UsersProjectsRoles.USERS_PROJECTS_ROLES; + /** * The table USERS_TEAMS. */ @@ -485,6 +503,8 @@ public final List> getTables() { ProjectsTags.PROJECTS_TAGS, Repository.REPOSITORY, RepositoryMetaComponent.REPOSITORY_META_COMPONENT, + Role.ROLE, + RolesPermissions.ROLES_PERMISSIONS, ServiceComponent.SERVICECOMPONENT, ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES, Tag.TAG, @@ -493,6 +513,7 @@ public final List> getTables() { User.USER, UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, UsersPermissions.USERS_PERMISSIONS, + UsersProjectsRoles.USERS_PROJECTS_ROLES, UsersTeams.USERS_TEAMS, Vex.VEX, ViolationAnalysis.VIOLATIONANALYSIS, diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java index daa724832f..6182ea8d3a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java @@ -34,10 +34,12 @@ import org.dependencytrack.persistence.jooq.generated.tables.ProjectMetadata; import org.dependencytrack.persistence.jooq.generated.tables.Repository; import org.dependencytrack.persistence.jooq.generated.tables.RepositoryMetaComponent; +import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponent; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponentsVulnerabilities; import org.dependencytrack.persistence.jooq.generated.tables.Tag; import org.dependencytrack.persistence.jooq.generated.tables.User; +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysisComment; @@ -60,7 +62,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @@ -147,6 +149,8 @@ public class Indexes { public static final Index REPOSITORY_META_COMPONENT_COMPOUND_IDX = Internal.createIndex(DSL.name("REPOSITORY_META_COMPONENT_COMPOUND_IDX"), RepositoryMetaComponent.REPOSITORY_META_COMPONENT, new OrderField[] { RepositoryMetaComponent.REPOSITORY_META_COMPONENT.repositoryType, RepositoryMetaComponent.REPOSITORY_META_COMPONENT.namespace, RepositoryMetaComponent.REPOSITORY_META_COMPONENT.name }, true); public static final Index REPOSITORY_META_COMPONENT_LASTCHECK_IDX = Internal.createIndex(DSL.name("REPOSITORY_META_COMPONENT_LASTCHECK_IDX"), RepositoryMetaComponent.REPOSITORY_META_COMPONENT, new OrderField[] { RepositoryMetaComponent.REPOSITORY_META_COMPONENT.lastCheck }, false); public static final Index REPOSITORY_UUID_IDX = Internal.createIndex(DSL.name("REPOSITORY_UUID_IDX"), Repository.REPOSITORY, new OrderField[] { Repository.REPOSITORY.uuid }, false); + public static final Index ROLES_PERMISSIONS_PERMISSION_ID_IDX = Internal.createIndex(DSL.name("ROLES_PERMISSIONS_PERMISSION_ID_IDX"), RolesPermissions.ROLES_PERMISSIONS, new OrderField[] { RolesPermissions.ROLES_PERMISSIONS.permissionId }, false); + public static final Index ROLES_PERMISSIONS_ROLE_ID_IDX = Internal.createIndex(DSL.name("ROLES_PERMISSIONS_ROLE_ID_IDX"), RolesPermissions.ROLES_PERMISSIONS, new OrderField[] { RolesPermissions.ROLES_PERMISSIONS.roleId }, false); public static final Index SERVICECOMPONENT_LAST_RISKSCORE_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENT_LAST_RISKSCORE_IDX"), ServiceComponent.SERVICECOMPONENT, new OrderField[] { ServiceComponent.SERVICECOMPONENT.lastRiskScore }, false); public static final Index SERVICECOMPONENT_PARENT_SERVICECOMPONENT_ID_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENT_PARENT_SERVICECOMPONENT_ID_IDX"), ServiceComponent.SERVICECOMPONENT, new OrderField[] { ServiceComponent.SERVICECOMPONENT.parentServiceComponentId }, false); public static final Index SERVICECOMPONENT_PROJECT_ID_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENT_PROJECT_ID_IDX"), ServiceComponent.SERVICECOMPONENT, new OrderField[] { ServiceComponent.SERVICECOMPONENT.projectId }, false); @@ -154,6 +158,8 @@ public class Indexes { public static final Index SERVICECOMPONENTS_VULNERABILITIES_VULNERABILITY_ID_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENTS_VULNERABILITIES_VULNERABILITY_ID_IDX"), ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES, new OrderField[] { ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES.vulnerabilityId }, false); public static final Index TAG_NAME_IDX = Internal.createIndex(DSL.name("TAG_NAME_IDX"), Tag.TAG, new OrderField[] { Tag.TAG.name }, true); public static final Index USER_USERNAME_IDX = Internal.createIndex(DSL.name("USER_USERNAME_IDX"), User.USER, new OrderField[] { User.USER.username }, true); + public static final Index USERS_PROJECTS_ROLES_ROLE_ID_IDX = Internal.createIndex(DSL.name("USERS_PROJECTS_ROLES_ROLE_ID_IDX"), UsersProjectsRoles.USERS_PROJECTS_ROLES, new OrderField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.roleId }, false); + public static final Index USERS_PROJECTS_ROLES_USER_PROJECT_IDX = Internal.createIndex(DSL.name("USERS_PROJECTS_ROLES_USER_PROJECT_IDX"), UsersProjectsRoles.USERS_PROJECTS_ROLES, new OrderField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.userId, UsersProjectsRoles.USERS_PROJECTS_ROLES.projectId }, true); public static final Index VEX_PROJECT_ID_IDX = Internal.createIndex(DSL.name("VEX_PROJECT_ID_IDX"), Vex.VEX, new OrderField[] { Vex.VEX.projectId }, false); public static final Index VIOLATIONANALYSIS_COMPONENT_ID_IDX = Internal.createIndex(DSL.name("VIOLATIONANALYSIS_COMPONENT_ID_IDX"), ViolationAnalysis.VIOLATIONANALYSIS, new OrderField[] { ViolationAnalysis.VIOLATIONANALYSIS.componentId }, false); public static final Index VIOLATIONANALYSIS_POLICYVIOLATION_ID_IDX = Internal.createIndex(DSL.name("VIOLATIONANALYSIS_POLICYVIOLATION_ID_IDX"), ViolationAnalysis.VIOLATIONANALYSIS, new OrderField[] { ViolationAnalysis.VIOLATIONANALYSIS.policyViolationId }, false); diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java index bb3fdc4e36..6b98a520d2 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java @@ -49,6 +49,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.ProjectsTags; import org.dependencytrack.persistence.jooq.generated.tables.Repository; import org.dependencytrack.persistence.jooq.generated.tables.RepositoryMetaComponent; +import org.dependencytrack.persistence.jooq.generated.tables.Role; +import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponent; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponentsVulnerabilities; import org.dependencytrack.persistence.jooq.generated.tables.Tag; @@ -57,6 +59,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -114,6 +117,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectsTagsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.RepositoryMetaComponentRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.RepositoryRecord; +import org.dependencytrack.persistence.jooq.generated.tables.records.RoleRecord; +import org.dependencytrack.persistence.jooq.generated.tables.records.RolesPermissionsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.ServiceComponentRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.ServiceComponentsVulnerabilitiesRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.TagRecord; @@ -122,6 +127,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.records.UserProjectEffectivePermissionsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UserRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UsersPermissionsRecord; +import org.dependencytrack.persistence.jooq.generated.tables.records.UsersProjectsRolesRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UsersTeamsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.VexRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.ViolationAnalysisCommentRecord; @@ -152,7 +158,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @@ -225,6 +231,10 @@ public class Keys { public static final UniqueKey REPOSITORY_COMPOUND_IDX = Internal.createUniqueKey(Repository.REPOSITORY, DSL.name("REPOSITORY_COMPOUND_IDX"), new TableField[] { Repository.REPOSITORY.type, Repository.REPOSITORY.identifier }, true); public static final UniqueKey REPOSITORY_PK = Internal.createUniqueKey(Repository.REPOSITORY, DSL.name("REPOSITORY_PK"), new TableField[] { Repository.REPOSITORY.id }, true); public static final UniqueKey REPOSITORY_META_COMPONENT_PK = Internal.createUniqueKey(RepositoryMetaComponent.REPOSITORY_META_COMPONENT, DSL.name("REPOSITORY_META_COMPONENT_PK"), new TableField[] { RepositoryMetaComponent.REPOSITORY_META_COMPONENT.id }, true); + public static final UniqueKey ROLE_NAME_IDX = Internal.createUniqueKey(Role.ROLE, DSL.name("ROLE_NAME_IDX"), new TableField[] { Role.ROLE.name }, true); + public static final UniqueKey ROLE_PK = Internal.createUniqueKey(Role.ROLE, DSL.name("ROLE_PK"), new TableField[] { Role.ROLE.id }, true); + public static final UniqueKey ROLE_UUID_IDX = Internal.createUniqueKey(Role.ROLE, DSL.name("ROLE_UUID_IDX"), new TableField[] { Role.ROLE.uuid }, true); + public static final UniqueKey ROLES_PERMISSIONS_COMPOSITE_IDX = Internal.createUniqueKey(RolesPermissions.ROLES_PERMISSIONS, DSL.name("ROLES_PERMISSIONS_COMPOSITE_IDX"), new TableField[] { RolesPermissions.ROLES_PERMISSIONS.roleId, RolesPermissions.ROLES_PERMISSIONS.permissionId }, true); public static final UniqueKey SERVICECOMPONENT_PK = Internal.createUniqueKey(ServiceComponent.SERVICECOMPONENT, DSL.name("SERVICECOMPONENT_PK"), new TableField[] { ServiceComponent.SERVICECOMPONENT.id }, true); public static final UniqueKey SERVICECOMPONENT_UUID_IDX = Internal.createUniqueKey(ServiceComponent.SERVICECOMPONENT, DSL.name("SERVICECOMPONENT_UUID_IDX"), new TableField[] { ServiceComponent.SERVICECOMPONENT.uuid }, true); public static final UniqueKey TAG_PK = Internal.createUniqueKey(Tag.TAG, DSL.name("TAG_PK"), new TableField[] { Tag.TAG.id }, true); @@ -314,6 +324,8 @@ public class Keys { public static final ForeignKey PROJECTMETRICS_PROJECT_FK = Internal.createForeignKey(ProjectMetrics.PROJECTMETRICS, DSL.name("PROJECTMETRICS_PROJECT_FK"), new TableField[] { ProjectMetrics.PROJECTMETRICS.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey PROJECTS_TAGS_PROJECT_FK = Internal.createForeignKey(ProjectsTags.PROJECTS_TAGS, DSL.name("PROJECTS_TAGS_PROJECT_FK"), new TableField[] { ProjectsTags.PROJECTS_TAGS.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey PROJECTS_TAGS_TAG_FK = Internal.createForeignKey(ProjectsTags.PROJECTS_TAGS, DSL.name("PROJECTS_TAGS_TAG_FK"), new TableField[] { ProjectsTags.PROJECTS_TAGS.tagId }, Keys.TAG_PK, new TableField[] { Tag.TAG.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey ROLES_PERMISSIONS_PERMISSION_FK = Internal.createForeignKey(RolesPermissions.ROLES_PERMISSIONS, DSL.name("ROLES_PERMISSIONS_PERMISSION_FK"), new TableField[] { RolesPermissions.ROLES_PERMISSIONS.permissionId }, Keys.PERMISSION_PK, new TableField[] { Permission.PERMISSION.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey ROLES_PERMISSIONS_ROLE_FK = Internal.createForeignKey(RolesPermissions.ROLES_PERMISSIONS, DSL.name("ROLES_PERMISSIONS_ROLE_FK"), new TableField[] { RolesPermissions.ROLES_PERMISSIONS.roleId }, Keys.ROLE_PK, new TableField[] { Role.ROLE.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey SERVICECOMPONENT_PROJECT_FK = Internal.createForeignKey(ServiceComponent.SERVICECOMPONENT, DSL.name("SERVICECOMPONENT_PROJECT_FK"), new TableField[] { ServiceComponent.SERVICECOMPONENT.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey SERVICECOMPONENT_SERVICECOMPONENT_FK = Internal.createForeignKey(ServiceComponent.SERVICECOMPONENT, DSL.name("SERVICECOMPONENT_SERVICECOMPONENT_FK"), new TableField[] { ServiceComponent.SERVICECOMPONENT.parentServiceComponentId }, Keys.SERVICECOMPONENT_PK, new TableField[] { ServiceComponent.SERVICECOMPONENT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey SERVICECOMPONENTS_VULNERABILITIES_SERVICECOMPONENT_FK = Internal.createForeignKey(ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES, DSL.name("SERVICECOMPONENTS_VULNERABILITIES_SERVICECOMPONENT_FK"), new TableField[] { ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES.serviceComponentId }, Keys.SERVICECOMPONENT_PK, new TableField[] { ServiceComponent.SERVICECOMPONENT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); @@ -326,6 +338,9 @@ public class Keys { public static final ForeignKey USER_PROJECT_EFFECTIVE_PERMISSIONS_USER_FK = Internal.createForeignKey(UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, DSL.name("USER_PROJECT_EFFECTIVE_PERMISSIONS_USER_FK"), new TableField[] { UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_PERMISSIONS_PERMISSION_FK = Internal.createForeignKey(UsersPermissions.USERS_PERMISSIONS, DSL.name("USERS_PERMISSIONS_PERMISSION_FK"), new TableField[] { UsersPermissions.USERS_PERMISSIONS.permissionId }, Keys.PERMISSION_PK, new TableField[] { Permission.PERMISSION.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_PERMISSIONS_USER_FK = Internal.createForeignKey(UsersPermissions.USERS_PERMISSIONS, DSL.name("USERS_PERMISSIONS_USER_FK"), new TableField[] { UsersPermissions.USERS_PERMISSIONS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey USERS_PROJECTS_ROLES_PROJECT_FK = Internal.createForeignKey(UsersProjectsRoles.USERS_PROJECTS_ROLES, DSL.name("USERS_PROJECTS_ROLES_PROJECT_FK"), new TableField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey USERS_PROJECTS_ROLES_ROLE_FK = Internal.createForeignKey(UsersProjectsRoles.USERS_PROJECTS_ROLES, DSL.name("USERS_PROJECTS_ROLES_ROLE_FK"), new TableField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.roleId }, Keys.ROLE_PK, new TableField[] { Role.ROLE.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey USERS_PROJECTS_ROLES_USER_FK = Internal.createForeignKey(UsersProjectsRoles.USERS_PROJECTS_ROLES, DSL.name("USERS_PROJECTS_ROLES_USER_FK"), new TableField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_TEAMS_TEAM_FK = Internal.createForeignKey(UsersTeams.USERS_TEAMS, DSL.name("USERS_TEAMS_TEAM_FK"), new TableField[] { UsersTeams.USERS_TEAMS.teamId }, Keys.TEAM_PK, new TableField[] { Team.TEAM.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_TEAMS_USER_FK = Internal.createForeignKey(UsersTeams.USERS_TEAMS, DSL.name("USERS_TEAMS_USER_FK"), new TableField[] { UsersTeams.USERS_TEAMS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey VEX_PROJECT_FK = Internal.createForeignKey(Vex.VEX, DSL.name("VEX_PROJECT_FK"), new TableField[] { Vex.VEX.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java index b2d71758d9..7ac47f6814 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java @@ -13,6 +13,7 @@ import org.dependencytrack.persistence.jooq.generated.routines.HasProjectAccess; import org.dependencytrack.persistence.jooq.generated.routines.JsonbVulnAliases; import org.dependencytrack.persistence.jooq.generated.routines.RecalcUserProjectEffectivePermissions; +import org.dependencytrack.persistence.jooq.generated.routines.RecalcUserProjectRoleEffectivePermissions; import org.dependencytrack.persistence.jooq.generated.routines.UpdateComponentMetrics; import org.dependencytrack.persistence.jooq.generated.routines.UpdatePortfolioMetrics; import org.dependencytrack.persistence.jooq.generated.routines.UpdateProjectMetrics; @@ -29,7 +30,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @@ -199,6 +200,19 @@ public static void recalcUserProjectEffectivePermissions( p.execute(configuration); } + /** + * Call recalc_user_project_role_effective_permissions + */ + public static void recalcUserProjectRoleEffectivePermissions( + Configuration configuration + , Long[] projectIds + ) { + RecalcUserProjectRoleEffectivePermissions p = new RecalcUserProjectRoleEffectivePermissions(); + p.setProjectIds(projectIds); + + p.execute(configuration); + } + /** * Call UPDATE_COMPONENT_METRICS */ diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java index ca998f2e3c..e92954215b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java @@ -49,6 +49,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.ProjectsTags; import org.dependencytrack.persistence.jooq.generated.tables.Repository; import org.dependencytrack.persistence.jooq.generated.tables.RepositoryMetaComponent; +import org.dependencytrack.persistence.jooq.generated.tables.Role; +import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponent; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponentsVulnerabilities; import org.dependencytrack.persistence.jooq.generated.tables.Tag; @@ -57,6 +59,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -80,7 +83,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @@ -302,6 +305,16 @@ public class Tables { */ public static final RepositoryMetaComponent REPOSITORY_META_COMPONENT = RepositoryMetaComponent.REPOSITORY_META_COMPONENT; + /** + * The table ROLE. + */ + public static final Role ROLE = Role.ROLE; + + /** + * The table ROLES_PERMISSIONS. + */ + public static final RolesPermissions ROLES_PERMISSIONS = RolesPermissions.ROLES_PERMISSIONS; + /** * The table SERVICECOMPONENT. */ @@ -342,6 +355,11 @@ public class Tables { */ public static final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; + /** + * The table USERS_PROJECTS_ROLES. + */ + public static final UsersProjectsRoles USERS_PROJECTS_ROLES = UsersProjectsRoles.USERS_PROJECTS_ROLES; + /** * The table USERS_TEAMS. */ diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java index 54444a2170..633b2102fe 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java @@ -19,7 +19,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java index 28539daa08..8993cf3f17 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java @@ -24,14 +24,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class CalcRiskScore extends AbstractRoutine { - private static final long serialVersionUID = -234719986; + private static final long serialVersionUID = -2141815729; /** * The parameter CALC_RISK_SCORE.RETURN_VALUE. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java index 2ce6fa15c5..23e62fcde4 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java @@ -22,14 +22,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class HasProjectAccess extends AbstractRoutine { - private static final long serialVersionUID = 493440600; + private static final long serialVersionUID = 1366074265; /** * The parameter has_project_access.RETURN_VALUE. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java index dfc350f35b..e74a0899a3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class JsonbVulnAliases extends AbstractRoutine { - private static final long serialVersionUID = 676127199; + private static final long serialVersionUID = -1914958624; /** * The parameter jsonb_vuln_aliases.RETURN_VALUE. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java index c9be554f12..9d8a1c1f33 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RecalcUserProjectEffectivePermissions extends AbstractRoutine { - private static final long serialVersionUID = -199375943; + private static final long serialVersionUID = -2142402630; /** * The parameter diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java new file mode 100644 index 0000000000..4f50b5d7d9 --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java @@ -0,0 +1,54 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.routines; + + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.DefaultSchema; +import org.jooq.Parameter; +import org.jooq.impl.AbstractRoutine; +import org.jooq.impl.DSL; +import org.jooq.impl.Internal; +import org.jooq.impl.SQLDataType; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class RecalcUserProjectRoleEffectivePermissions extends AbstractRoutine { + + private static final long serialVersionUID = 2073358932; + + /** + * The parameter + * recalc_user_project_role_effective_permissions.project_ids. + */ + public static final Parameter PROJECT_IDS = Internal.createParameter("project_ids", SQLDataType.BIGINT.array(), false, false); + + /** + * Create a new routine call instance + */ + public RecalcUserProjectRoleEffectivePermissions() { + super("recalc_user_project_role_effective_permissions", DefaultSchema.DEFAULT_SCHEMA, DSL.comment("")); + + addInParameter(PROJECT_IDS); + } + + /** + * Set the project_ids parameter IN value to the routine + */ + public void setProjectIds(Long[] value) { + setValue(PROJECT_IDS, value); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java index dc63b9da7c..b761cba401 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UpdateComponentMetrics extends AbstractRoutine { - private static final long serialVersionUID = 196404148; + private static final long serialVersionUID = -1702575277; /** * The parameter UPDATE_COMPONENT_METRICS.component_uuid. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java index 2d1eaa197b..bde55628d8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UpdatePortfolioMetrics extends AbstractRoutine { - private static final long serialVersionUID = -1769165488; + private static final long serialVersionUID = 1444263983; /** * Create a new routine call instance diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java index af7331d12b..4a067a768d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UpdateProjectMetrics extends AbstractRoutine { - private static final long serialVersionUID = -887799344; + private static final long serialVersionUID = -612851025; /** * The parameter UPDATE_PROJECT_METRICS.project_uuid. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java index cf4070d9d0..1c12933d5c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AffectedVersionAttribution extends TableImpl { - private static final long serialVersionUID = 1249866150; + private static final long serialVersionUID = -938219356; /** * The reference instance of AFFECTEDVERSIONATTRIBUTION @@ -146,13 +146,13 @@ public AffectedVersionAttribution(Table path, ForeignKey { - private static final long serialVersionUID = 1249866150; + private static final long serialVersionUID = -938219356; public AffectedVersionAttributionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java index 1937033f4c..79cc5cd650 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java @@ -52,14 +52,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Analysis extends TableImpl { - private static final long serialVersionUID = -1637442219; + private static final long serialVersionUID = -676941835; /** * The reference instance of ANALYSIS @@ -199,13 +199,13 @@ public Analysis(Table path, ForeignKey value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class AnalysisPath extends Analysis implements Path { - private static final long serialVersionUID = -1637442219; + private static final long serialVersionUID = -676941835; public AnalysisPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java index 47151c5398..e177fa9b31 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AnalysisComment extends TableImpl { - private static final long serialVersionUID = 614853088; + private static final long serialVersionUID = 67920414; /** * The reference instance of ANALYSISCOMMENT @@ -134,13 +134,13 @@ public AnalysisComment(Table path, ForeignKey { - private static final long serialVersionUID = 614853088; + private static final long serialVersionUID = 67920414; public AnalysisCommentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java index 77546139fd..8b8de0594f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKey extends TableImpl { - private static final long serialVersionUID = 1411726765; + private static final long serialVersionUID = -711465365; /** * The reference instance of APIKEY @@ -145,13 +145,13 @@ public ApiKey(Table path, ForeignKey chil value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class ApiKeyPath extends ApiKey implements Path { - private static final long serialVersionUID = 1411726765; + private static final long serialVersionUID = -711465365; public ApiKeyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java index bdab8a96fe..77c31c58e3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKeysTeams extends TableImpl { - private static final long serialVersionUID = -1676545580; + private static final long serialVersionUID = -1570762444; /** * The reference instance of APIKEYS_TEAMS @@ -116,13 +116,13 @@ public ApiKeysTeams(Table path, ForeignKey { - private static final long serialVersionUID = -1676545580; + private static final long serialVersionUID = -1570762444; public ApiKeysTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java index e86fc81632..95b444ad30 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Bom extends TableImpl { - private static final long serialVersionUID = -781209064; + private static final long serialVersionUID = -979504904; /** * The reference instance of BOM @@ -155,13 +155,13 @@ public Bom(Table path, ForeignKey childPath, value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class BomPath extends Bom implements Path { - private static final long serialVersionUID = -781209064; + private static final long serialVersionUID = -979504904; public BomPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java index 5b83253f7d..f185bdb339 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java @@ -61,14 +61,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Component extends TableImpl { - private static final long serialVersionUID = -117754819; + private static final long serialVersionUID = -1731235713; /** * The reference instance of COMPONENT @@ -323,13 +323,13 @@ public Component(Table path, ForeignKey { - private static final long serialVersionUID = -117754819; + private static final long serialVersionUID = -1731235713; public ComponentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java index 831e3085ed..1a6636480a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentOccurrence extends TableImpl { - private static final long serialVersionUID = 1203110904; + private static final long serialVersionUID = -1139580904; /** * The reference instance of COMPONENT_OCCURRENCE @@ -144,13 +144,13 @@ public ComponentOccurrence(Table path, ForeignKey { - private static final long serialVersionUID = 1203110904; + private static final long serialVersionUID = -1139580904; public ComponentOccurrencePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java index b1f4b4ed2b..385e93e1c7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentProperty extends TableImpl { - private static final long serialVersionUID = 2092165140; + private static final long serialVersionUID = 2142097110; /** * The reference instance of COMPONENT_PROPERTY @@ -151,13 +151,13 @@ public ComponentProperty(Table path, ForeignKey { - private static final long serialVersionUID = 2092165140; + private static final long serialVersionUID = 2142097110; public ComponentPropertyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java index 44cea692e2..5b5b6e13ec 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentsVulnerabilities extends TableImpl { - private static final long serialVersionUID = 2102850516; + private static final long serialVersionUID = -2111707182; /** * The reference instance of COMPONENTS_VULNERABILITIES @@ -117,13 +117,13 @@ public ComponentsVulnerabilities(Table path, ForeignKey { - private static final long serialVersionUID = 2102850516; + private static final long serialVersionUID = -2111707182; public ComponentsVulnerabilitiesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java index 4150e0daea..865ddcbf2f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java @@ -39,14 +39,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ConfigProperty extends TableImpl { - private static final long serialVersionUID = -914264675; + private static final long serialVersionUID = -1963189124; /** * The reference instance of CONFIGPROPERTY diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java index f50cb63bd1..1e8cff1cdf 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class DependencyMetrics extends TableImpl { - private static final long serialVersionUID = -302376119; + private static final long serialVersionUID = -589450869; /** * The reference instance of DEPENDENCYMETRICS @@ -265,13 +265,13 @@ public DependencyMetrics(Table path, ForeignKey { - private static final long serialVersionUID = -302376119; + private static final long serialVersionUID = -589450869; public DependencyMetricsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java index 808b243b07..126041a6c7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Epss extends TableImpl { - private static final long serialVersionUID = 430616880; + private static final long serialVersionUID = 1806497615; /** * The reference instance of EPSS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java index cd261fa117..ad6073cd40 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java @@ -50,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class FindingAttribution extends TableImpl { - private static final long serialVersionUID = 739551873; + private static final long serialVersionUID = -1832451837; /** * The reference instance of FINDINGATTRIBUTION @@ -157,13 +157,13 @@ public FindingAttribution(Table path, ForeignKey { - private static final long serialVersionUID = 739551873; + private static final long serialVersionUID = -1832451837; public FindingAttributionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java index 03386bb11a..dfccb4a670 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityAnalysis extends TableImpl { - private static final long serialVersionUID = 1603200635; + private static final long serialVersionUID = -1888012935; /** * The reference instance of INTEGRITY_ANALYSIS @@ -149,13 +149,13 @@ public IntegrityAnalysis(Table path, ForeignKey { - private static final long serialVersionUID = 1603200635; + private static final long serialVersionUID = -1888012935; public IntegrityAnalysisPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java index f2c5e41c91..84856f58c6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityMetaComponent extends TableImpl { - private static final long serialVersionUID = -461523102; + private static final long serialVersionUID = -1317194047; /** * The reference instance of INTEGRITY_META_COMPONENT diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java index 35c572cd0a..011ae0778d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class License extends TableImpl { - private static final long serialVersionUID = -386899321; + private static final long serialVersionUID = 660778313; /** * The reference instance of LICENSE @@ -175,13 +175,13 @@ public License(Table path, ForeignKey ch value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class LicensePath extends License implements Path { - private static final long serialVersionUID = -386899321; + private static final long serialVersionUID = 660778313; public LicensePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java index fdf9df330a..ffcbe3ab51 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroup extends TableImpl { - private static final long serialVersionUID = 1380687068; + private static final long serialVersionUID = 1648671036; /** * The reference instance of LICENSEGROUP @@ -129,13 +129,13 @@ public LicenseGroup(Table path, ForeignKey { - private static final long serialVersionUID = 1380687068; + private static final long serialVersionUID = 1648671036; public LicenseGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java index 68cdf4d699..fb731ddec5 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroupLicense extends TableImpl { - private static final long serialVersionUID = -249804984; + private static final long serialVersionUID = 224650408; /** * The reference instance of LICENSEGROUP_LICENSE @@ -117,13 +117,13 @@ public LicenseGroupLicense(Table path, ForeignKey { - private static final long serialVersionUID = -249804984; + private static final long serialVersionUID = 224650408; public LicenseGroupLicensePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java index 705a0b9000..0ff959fd1c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedLdapGroup extends TableImpl { - private static final long serialVersionUID = 109596849; + private static final long serialVersionUID = 1776230963; /** * The reference instance of MAPPEDLDAPGROUP @@ -126,13 +126,13 @@ public MappedLdapGroup(Table path, ForeignKey { - private static final long serialVersionUID = 109596849; + private static final long serialVersionUID = 1776230963; public MappedLdapGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java index 6dca2d263f..d46720a004 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedOidcGroup extends TableImpl { - private static final long serialVersionUID = 682827561; + private static final long serialVersionUID = 610435687; /** * The reference instance of MAPPEDOIDCGROUP @@ -129,13 +129,13 @@ public MappedOidcGroup(Table path, ForeignKey { - private static final long serialVersionUID = 682827561; + private static final long serialVersionUID = 610435687; public MappedOidcGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java index 6a7ae469a4..d4ea29e6eb 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationPublisher extends TableImpl { - private static final long serialVersionUID = 1027440007; + private static final long serialVersionUID = -1076695095; /** * The reference instance of NOTIFICATIONPUBLISHER @@ -147,13 +147,13 @@ public NotificationPublisher(Table path, ForeignKey { - private static final long serialVersionUID = 1027440007; + private static final long serialVersionUID = -1076695095; public NotificationPublisherPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java index 8240fa98f8..9c0bae12af 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java @@ -52,14 +52,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRule extends TableImpl { - private static final long serialVersionUID = -829707404; + private static final long serialVersionUID = 1113696852; /** * The reference instance of NOTIFICATIONRULE @@ -174,13 +174,13 @@ public NotificationRule(Table path, ForeignKey { - private static final long serialVersionUID = -829707404; + private static final long serialVersionUID = 1113696852; public NotificationRulePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java index af764a67bb..2eaf3bd7f3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleProjects extends TableImpl { - private static final long serialVersionUID = 133247742; + private static final long serialVersionUID = 810213248; /** * The reference instance of NOTIFICATIONRULE_PROJECTS @@ -117,13 +117,13 @@ public NotificationRuleProjects(Table path, ForeignKey { - private static final long serialVersionUID = 133247742; + private static final long serialVersionUID = 810213248; public NotificationRuleProjectsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java index 3f3a5ec9b2..2209a6d143 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTags extends TableImpl { - private static final long serialVersionUID = 1910248840; + private static final long serialVersionUID = 1998603530; /** * The reference instance of NOTIFICATIONRULE_TAGS @@ -116,13 +116,13 @@ public NotificationRuleTags(Table path, ForeignKey { - private static final long serialVersionUID = 1910248840; + private static final long serialVersionUID = 1998603530; public NotificationRuleTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java index 7a95f81469..ff730d97df 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTeams extends TableImpl { - private static final long serialVersionUID = -1962593340; + private static final long serialVersionUID = 802684418; /** * The reference instance of NOTIFICATIONRULE_TEAMS @@ -116,13 +116,13 @@ public NotificationRuleTeams(Table path, ForeignKey { - private static final long serialVersionUID = -1962593340; + private static final long serialVersionUID = 802684418; public NotificationRuleTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java index b4435efac6..23e91a6b06 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java @@ -46,14 +46,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class OidcGroup extends TableImpl { - private static final long serialVersionUID = 306753486; + private static final long serialVersionUID = -561573330; /** * The reference instance of OIDCGROUP @@ -123,13 +123,13 @@ public OidcGroup(Table path, ForeignKey { - private static final long serialVersionUID = 306753486; + private static final long serialVersionUID = -561573330; public OidcGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java index c93f60634c..35345c8419 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java @@ -12,6 +12,8 @@ import org.dependencytrack.persistence.jooq.generated.DefaultSchema; import org.dependencytrack.persistence.jooq.generated.Keys; +import org.dependencytrack.persistence.jooq.generated.tables.Role.RolePath; +import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions.RolesPermissionsPath; import org.dependencytrack.persistence.jooq.generated.tables.Team.TeamPath; import org.dependencytrack.persistence.jooq.generated.tables.TeamsPermissions.TeamsPermissionsPath; import org.dependencytrack.persistence.jooq.generated.tables.User.UserPath; @@ -48,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Permission extends TableImpl { - private static final long serialVersionUID = -710656376; + private static final long serialVersionUID = 1134556928; /** * The reference instance of PERMISSION @@ -125,13 +127,13 @@ public Permission(Table path, ForeignKey { - private static final long serialVersionUID = -710656376; + private static final long serialVersionUID = 1134556928; public PermissionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } @@ -175,6 +177,19 @@ public List> getUniqueKeys() { return Arrays.asList(Keys.PERMISSION_IDX); } + private transient RolesPermissionsPath _rolesPermissions; + + /** + * Get the implicit to-many join path to the ROLES_PERMISSIONS + * table + */ + public RolesPermissionsPath rolesPermissions() { + if (_rolesPermissions == null) + _rolesPermissions = new RolesPermissionsPath(this, null, Keys.ROLES_PERMISSIONS_PERMISSION_FK.getInverseKey()); + + return _rolesPermissions; + } + private transient TeamsPermissionsPath _teamsPermissions; /** @@ -229,6 +244,13 @@ public UsersPermissionsPath usersPermissions() { return _usersPermissions; } + /** + * Get the implicit many-to-many join path to the ROLE table + */ + public RolePath role() { + return rolesPermissions().role(); + } + /** * Get the implicit many-to-many join path to the TEAM table */ diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java index 12a5b9298f..03cacc345f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java @@ -50,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Policy extends TableImpl { - private static final long serialVersionUID = 413951221; + private static final long serialVersionUID = -763533389; /** * The reference instance of POLICY @@ -147,13 +147,13 @@ public Policy(Table path, ForeignKey chil value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class PolicyPath extends Policy implements Path { - private static final long serialVersionUID = 413951221; + private static final long serialVersionUID = -763533389; public PolicyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java index 373a933875..0419247592 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyCondition extends TableImpl { - private static final long serialVersionUID = 1698155959; + private static final long serialVersionUID = -765297543; /** * The reference instance of POLICYCONDITION @@ -145,13 +145,13 @@ public PolicyCondition(Table path, ForeignKey { - private static final long serialVersionUID = 1698155959; + private static final long serialVersionUID = -765297543; public PolicyConditionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java index fd47c2e4b4..ee93f6bbcf 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyProjects extends TableImpl { - private static final long serialVersionUID = -1682094743; + private static final long serialVersionUID = -599792149; /** * The reference instance of POLICY_PROJECTS @@ -117,13 +117,13 @@ public PolicyProjects(Table path, ForeignKey { - private static final long serialVersionUID = -1682094743; + private static final long serialVersionUID = -599792149; public PolicyProjectsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java index ad47948116..f4336355ee 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyTags extends TableImpl { - private static final long serialVersionUID = -2032947896; + private static final long serialVersionUID = -971385270; /** * The reference instance of POLICY_TAGS @@ -116,13 +116,13 @@ public PolicyTags(Table path, ForeignKey { - private static final long serialVersionUID = -2032947896; + private static final long serialVersionUID = -971385270; public PolicyTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java index 4c7f7f24e7..7e9758d98d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java @@ -51,14 +51,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyViolation extends TableImpl { - private static final long serialVersionUID = 1539537451; + private static final long serialVersionUID = 1684309677; /** * The reference instance of POLICYVIOLATION @@ -153,13 +153,13 @@ public PolicyViolation(Table path, ForeignKey { - private static final long serialVersionUID = 1539537451; + private static final long serialVersionUID = 1684309677; public PolicyViolationPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java index 7fea10fb76..9a0df136e8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java @@ -37,14 +37,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PortfolioMetrics extends TableImpl { - private static final long serialVersionUID = 2016571758; + private static final long serialVersionUID = 1604183279; /** * The reference instance of PORTFOLIOMETRICS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java index e42b56db1e..244fa8918a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java @@ -34,6 +34,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.Tag.TagPath; import org.dependencytrack.persistence.jooq.generated.tables.Team.TeamPath; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions.UserProjectEffectivePermissionsPath; +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles.UsersProjectsRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.Vex.VexPath; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis.ViolationAnalysisPath; import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectRecord; @@ -71,14 +72,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Project extends TableImpl { - private static final long serialVersionUID = -266564691; + private static final long serialVersionUID = -1297445188; /** * The reference instance of PROJECT @@ -243,13 +244,13 @@ public Project(Table path, ForeignKey ch value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class ProjectPath extends Project implements Path { - private static final long serialVersionUID = -266564691; + private static final long serialVersionUID = -1297445188; public ProjectPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } @@ -533,6 +534,19 @@ public UserProjectEffectivePermissionsPath userProjectEffectivePermissions() { return _userProjectEffectivePermissions; } + private transient UsersProjectsRolesPath _usersProjectsRoles; + + /** + * Get the implicit to-many join path to the + * USERS_PROJECTS_ROLES table + */ + public UsersProjectsRolesPath usersProjectsRoles() { + if (_usersProjectsRoles == null) + _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.USERS_PROJECTS_ROLES_PROJECT_FK.getInverseKey()); + + return _usersProjectsRoles; + } + private transient VexPath _vex; /** diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java index 9ba46b6ca5..009718437f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectAccessTeams extends TableImpl { - private static final long serialVersionUID = 1439520474; + private static final long serialVersionUID = 873948858; /** * The reference instance of PROJECT_ACCESS_TEAMS @@ -116,13 +116,13 @@ public ProjectAccessTeams(Table path, ForeignKey { - private static final long serialVersionUID = 1439520474; + private static final long serialVersionUID = 873948858; public ProjectAccessTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java index 27c365f081..3f2cfd54ec 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java @@ -43,14 +43,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectHierarchy extends TableImpl { - private static final long serialVersionUID = 573413810; + private static final long serialVersionUID = 75786160; /** * The reference instance of PROJECT_HIERARCHY @@ -120,13 +120,13 @@ public ProjectHierarchy(Table path, ForeignKey { - private static final long serialVersionUID = 573413810; + private static final long serialVersionUID = 75786160; public ProjectHierarchyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java index 676b6fd87e..359b8b5a47 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java @@ -46,14 +46,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetadata extends TableImpl { - private static final long serialVersionUID = 1057573236; + private static final long serialVersionUID = 228933682; /** * The reference instance of PROJECT_METADATA @@ -133,13 +133,13 @@ public ProjectMetadata(Table path, ForeignKey { - private static final long serialVersionUID = 1057573236; + private static final long serialVersionUID = 228933682; public ProjectMetadataPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java index 624d2f10e8..12477b9928 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetrics extends TableImpl { - private static final long serialVersionUID = -1819192256; + private static final long serialVersionUID = -1382780670; /** * The reference instance of PROJECTMETRICS @@ -266,13 +266,13 @@ public ProjectMetrics(Table path, ForeignKey { - private static final long serialVersionUID = -1819192256; + private static final long serialVersionUID = -1382780670; public ProjectMetricsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java index 7c2df580ba..c5b1e9ea29 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectProperty extends TableImpl { - private static final long serialVersionUID = -1953659189; + private static final long serialVersionUID = 44418381; /** * The reference instance of PROJECT_PROPERTY @@ -141,13 +141,13 @@ public ProjectProperty(Table path, ForeignKey { - private static final long serialVersionUID = -1953659189; + private static final long serialVersionUID = 44418381; public ProjectPropertyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java index 3a32da735a..346fb62f47 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectsTags extends TableImpl { - private static final long serialVersionUID = -269722386; + private static final long serialVersionUID = -163939250; /** * The reference instance of PROJECTS_TAGS @@ -116,13 +116,13 @@ public ProjectsTags(Table path, ForeignKey { - private static final long serialVersionUID = -269722386; + private static final long serialVersionUID = -163939250; public ProjectsTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java index 49cb3f2297..7ddf8ff687 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Repository extends TableImpl { - private static final long serialVersionUID = -307753654; + private static final long serialVersionUID = 1139153193; /** * The reference instance of REPOSITORY diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java index a4ae28f46e..c370ea530d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RepositoryMetaComponent extends TableImpl { - private static final long serialVersionUID = -567367334; + private static final long serialVersionUID = 1187611547; /** * The reference instance of REPOSITORY_META_COMPONENT diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java new file mode 100644 index 0000000000..8092f464a2 --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java @@ -0,0 +1,333 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables; + + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.DefaultSchema; +import org.dependencytrack.persistence.jooq.generated.Keys; +import org.dependencytrack.persistence.jooq.generated.tables.Permission.PermissionPath; +import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions.RolesPermissionsPath; +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles.UsersProjectsRolesPath; +import org.dependencytrack.persistence.jooq.generated.tables.records.RoleRecord; +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Identity; +import org.jooq.InverseForeignKey; +import org.jooq.Name; +import org.jooq.Path; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.Record; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Role extends TableImpl { + + private static final long serialVersionUID = -1832423169; + + /** + * The reference instance of ROLE + */ + public static final Role ROLE = new Role(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return RoleRecord.class; + } + + /** + * The column ROLE.ID. + */ + public final TableField id = createField(DSL.name("ID"), SQLDataType.BIGINT.nullable(false).identity(true), this, ""); + + /** + * The column ROLE.NAME. + */ + public final TableField name = createField(DSL.name("NAME"), SQLDataType.VARCHAR(255).nullable(false), this, ""); + + /** + * The column ROLE.UUID. + */ + public final TableField uuid = createField(DSL.name("UUID"), SQLDataType.UUID.nullable(false), this, ""); + + private Role(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private Role(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased ROLE table reference + */ + public Role(String alias) { + this(DSL.name(alias), ROLE); + } + + /** + * Create an aliased ROLE table reference + */ + public Role(Name alias) { + this(alias, ROLE); + } + + /** + * Create a ROLE table reference + */ + public Role() { + this(DSL.name("ROLE"), null); + } + + public Role(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath, ROLE); + } + + /** + * A subtype implementing {@link Path} for simplified path-based joins. + */ + @Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" + ) + public static class RolePath extends Role implements Path { + + private static final long serialVersionUID = -1832423169; + public RolePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath); + } + private RolePath(Name alias, Table aliased) { + super(alias, aliased); + } + + @Override + public RolePath as(String alias) { + return new RolePath(DSL.name(alias), this); + } + + @Override + public RolePath as(Name alias) { + return new RolePath(alias, this); + } + + @Override + public RolePath as(Table alias) { + return new RolePath(alias.getQualifiedName(), this); + } + } + + @Override + public Schema getSchema() { + return aliased() ? null : DefaultSchema.DEFAULT_SCHEMA; + } + + @Override + public Identity getIdentity() { + return (Identity) super.getIdentity(); + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.ROLE_PK; + } + + @Override + public List> getUniqueKeys() { + return Arrays.asList(Keys.ROLE_NAME_IDX, Keys.ROLE_UUID_IDX); + } + + private transient RolesPermissionsPath _rolesPermissions; + + /** + * Get the implicit to-many join path to the ROLES_PERMISSIONS + * table + */ + public RolesPermissionsPath rolesPermissions() { + if (_rolesPermissions == null) + _rolesPermissions = new RolesPermissionsPath(this, null, Keys.ROLES_PERMISSIONS_ROLE_FK.getInverseKey()); + + return _rolesPermissions; + } + + private transient UsersProjectsRolesPath _usersProjectsRoles; + + /** + * Get the implicit to-many join path to the + * USERS_PROJECTS_ROLES table + */ + public UsersProjectsRolesPath usersProjectsRoles() { + if (_usersProjectsRoles == null) + _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.USERS_PROJECTS_ROLES_ROLE_FK.getInverseKey()); + + return _usersProjectsRoles; + } + + /** + * Get the implicit many-to-many join path to the PERMISSION + * table + */ + public PermissionPath permission() { + return rolesPermissions().permission(); + } + + @Override + public Role as(String alias) { + return new Role(DSL.name(alias), this); + } + + @Override + public Role as(Name alias) { + return new Role(alias, this); + } + + @Override + public Role as(Table alias) { + return new Role(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public Role rename(String name) { + return new Role(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Role rename(Name name) { + return new Role(name, null); + } + + /** + * Rename this table + */ + @Override + public Role rename(Table name) { + return new Role(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Role where(Condition condition) { + return new Role(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Role where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Role where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Role where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Role where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Role where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Role where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Role where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Role whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Role whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java new file mode 100644 index 0000000000..e783f8437e --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java @@ -0,0 +1,317 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables; + + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.DefaultSchema; +import org.dependencytrack.persistence.jooq.generated.Indexes; +import org.dependencytrack.persistence.jooq.generated.Keys; +import org.dependencytrack.persistence.jooq.generated.tables.Permission.PermissionPath; +import org.dependencytrack.persistence.jooq.generated.tables.Role.RolePath; +import org.dependencytrack.persistence.jooq.generated.tables.records.RolesPermissionsRecord; +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Index; +import org.jooq.InverseForeignKey; +import org.jooq.Name; +import org.jooq.Path; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.Record; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class RolesPermissions extends TableImpl { + + private static final long serialVersionUID = 188042180; + + /** + * The reference instance of ROLES_PERMISSIONS + */ + public static final RolesPermissions ROLES_PERMISSIONS = new RolesPermissions(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return RolesPermissionsRecord.class; + } + + /** + * The column ROLES_PERMISSIONS.ROLE_ID. + */ + public final TableField roleId = createField(DSL.name("ROLE_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + /** + * The column ROLES_PERMISSIONS.PERMISSION_ID. + */ + public final TableField permissionId = createField(DSL.name("PERMISSION_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + private RolesPermissions(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private RolesPermissions(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased ROLES_PERMISSIONS table reference + */ + public RolesPermissions(String alias) { + this(DSL.name(alias), ROLES_PERMISSIONS); + } + + /** + * Create an aliased ROLES_PERMISSIONS table reference + */ + public RolesPermissions(Name alias) { + this(alias, ROLES_PERMISSIONS); + } + + /** + * Create a ROLES_PERMISSIONS table reference + */ + public RolesPermissions() { + this(DSL.name("ROLES_PERMISSIONS"), null); + } + + public RolesPermissions(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath, ROLES_PERMISSIONS); + } + + /** + * A subtype implementing {@link Path} for simplified path-based joins. + */ + @Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" + ) + public static class RolesPermissionsPath extends RolesPermissions implements Path { + + private static final long serialVersionUID = 188042180; + public RolesPermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath); + } + private RolesPermissionsPath(Name alias, Table aliased) { + super(alias, aliased); + } + + @Override + public RolesPermissionsPath as(String alias) { + return new RolesPermissionsPath(DSL.name(alias), this); + } + + @Override + public RolesPermissionsPath as(Name alias) { + return new RolesPermissionsPath(alias, this); + } + + @Override + public RolesPermissionsPath as(Table alias) { + return new RolesPermissionsPath(alias.getQualifiedName(), this); + } + } + + @Override + public Schema getSchema() { + return aliased() ? null : DefaultSchema.DEFAULT_SCHEMA; + } + + @Override + public List getIndexes() { + return Arrays.asList(Indexes.ROLES_PERMISSIONS_PERMISSION_ID_IDX, Indexes.ROLES_PERMISSIONS_ROLE_ID_IDX); + } + + @Override + public List> getUniqueKeys() { + return Arrays.asList(Keys.ROLES_PERMISSIONS_COMPOSITE_IDX); + } + + @Override + public List> getReferences() { + return Arrays.asList(Keys.ROLES_PERMISSIONS_PERMISSION_FK, Keys.ROLES_PERMISSIONS_ROLE_FK); + } + + private transient PermissionPath _permission; + + /** + * Get the implicit join path to the PERMISSION table. + */ + public PermissionPath permission() { + if (_permission == null) + _permission = new PermissionPath(this, Keys.ROLES_PERMISSIONS_PERMISSION_FK, null); + + return _permission; + } + + private transient RolePath _role; + + /** + * Get the implicit join path to the ROLE table. + */ + public RolePath role() { + if (_role == null) + _role = new RolePath(this, Keys.ROLES_PERMISSIONS_ROLE_FK, null); + + return _role; + } + + @Override + public RolesPermissions as(String alias) { + return new RolesPermissions(DSL.name(alias), this); + } + + @Override + public RolesPermissions as(Name alias) { + return new RolesPermissions(alias, this); + } + + @Override + public RolesPermissions as(Table alias) { + return new RolesPermissions(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public RolesPermissions rename(String name) { + return new RolesPermissions(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public RolesPermissions rename(Name name) { + return new RolesPermissions(name, null); + } + + /** + * Rename this table + */ + @Override + public RolesPermissions rename(Table name) { + return new RolesPermissions(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public RolesPermissions where(Condition condition) { + return new RolesPermissions(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public RolesPermissions where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public RolesPermissions where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public RolesPermissions where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public RolesPermissions where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public RolesPermissions where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public RolesPermissions where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public RolesPermissions where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public RolesPermissions whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public RolesPermissions whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java index 3bb19a88e7..c5628dfa8d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponent extends TableImpl { - private static final long serialVersionUID = 1358781429; + private static final long serialVersionUID = -1366507819; /** * The reference instance of SERVICECOMPONENT @@ -191,13 +191,13 @@ public ServiceComponent(Table path, ForeignKey { - private static final long serialVersionUID = 1358781429; + private static final long serialVersionUID = -1366507819; public ServiceComponentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java index 83d4113913..daa582f4e6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponentsVulnerabilities extends TableImpl { - private static final long serialVersionUID = -1937052999; + private static final long serialVersionUID = -991095685; /** * The reference instance of SERVICECOMPONENTS_VULNERABILITIES @@ -121,13 +121,13 @@ public ServiceComponentsVulnerabilities(Table path, Foreig value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class ServiceComponentsVulnerabilitiesPath extends ServiceComponentsVulnerabilities implements Path { - private static final long serialVersionUID = -1937052999; + private static final long serialVersionUID = -991095685; public ServiceComponentsVulnerabilitiesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java index 79fbec2022..a57b60bee6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java @@ -52,14 +52,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Tag extends TableImpl { - private static final long serialVersionUID = -488236356; + private static final long serialVersionUID = -59691910; /** * The reference instance of TAG @@ -124,13 +124,13 @@ public Tag(Table path, ForeignKey childPath, value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class TagPath extends Tag implements Path { - private static final long serialVersionUID = -488236356; + private static final long serialVersionUID = -59691910; public TagPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java index a5ee2c0451..b73798a4f6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java @@ -53,14 +53,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Team extends TableImpl { - private static final long serialVersionUID = 1459546599; + private static final long serialVersionUID = 638132231; /** * The reference instance of TEAM @@ -130,13 +130,13 @@ public Team(Table path, ForeignKey childPat value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class TeamPath extends Team implements Path { - private static final long serialVersionUID = 1459546599; + private static final long serialVersionUID = 638132231; public TeamPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java index c5612c6e7a..10df9304d3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TeamsPermissions extends TableImpl { - private static final long serialVersionUID = 1337517628; + private static final long serialVersionUID = -1593956964; /** * The reference instance of TEAMS_PERMISSIONS @@ -116,13 +116,13 @@ public TeamsPermissions(Table path, ForeignKey { - private static final long serialVersionUID = 1337517628; + private static final long serialVersionUID = -1593956964; public TeamsPermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java index 80bcdf21c5..3505e8d1ab 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java @@ -18,6 +18,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.Team.TeamPath; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions.UserProjectEffectivePermissionsPath; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions.UsersPermissionsPath; +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles.UsersProjectsRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams.UsersTeamsPath; import org.dependencytrack.persistence.jooq.generated.tables.records.UserRecord; import org.jooq.Check; @@ -53,14 +54,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class User extends TableImpl { - private static final long serialVersionUID = 885897955; + private static final long serialVersionUID = -712068352; /** * The reference instance of USER @@ -175,13 +176,13 @@ public User(Table path, ForeignKey childPat value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class UserPath extends User implements Path { - private static final long serialVersionUID = 885897955; + private static final long serialVersionUID = -712068352; public UserPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } @@ -251,6 +252,19 @@ public UsersPermissionsPath usersPermissions() { return _usersPermissions; } + private transient UsersProjectsRolesPath _usersProjectsRoles; + + /** + * Get the implicit to-many join path to the + * USERS_PROJECTS_ROLES table + */ + public UsersProjectsRolesPath usersProjectsRoles() { + if (_usersProjectsRoles == null) + _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.USERS_PROJECTS_ROLES_USER_FK.getInverseKey()); + + return _usersProjectsRoles; + } + private transient UsersTeamsPath _usersTeams; /** diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java index dee608c2a8..4a45ced47d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UserProjectEffectivePermissions extends TableImpl { - private static final long serialVersionUID = -391019753; + private static final long serialVersionUID = 2035432985; /** * The reference instance of USER_PROJECT_EFFECTIVE_PERMISSIONS @@ -130,13 +130,13 @@ public UserProjectEffectivePermissions(Table path, Foreign value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class UserProjectEffectivePermissionsPath extends UserProjectEffectivePermissions implements Path { - private static final long serialVersionUID = -391019753; + private static final long serialVersionUID = 2035432985; public UserProjectEffectivePermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java index 723572239d..da021e3340 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersPermissions extends TableImpl { - private static final long serialVersionUID = 1724545700; + private static final long serialVersionUID = -1206928892; /** * The reference instance of USERS_PERMISSIONS @@ -116,13 +116,13 @@ public UsersPermissions(Table path, ForeignKey { - private static final long serialVersionUID = 1724545700; + private static final long serialVersionUID = -1206928892; public UsersPermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersProjectsRoles.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersProjectsRoles.java new file mode 100644 index 0000000000..174bb3074f --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersProjectsRoles.java @@ -0,0 +1,329 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables; + + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.DefaultSchema; +import org.dependencytrack.persistence.jooq.generated.Indexes; +import org.dependencytrack.persistence.jooq.generated.Keys; +import org.dependencytrack.persistence.jooq.generated.tables.Project.ProjectPath; +import org.dependencytrack.persistence.jooq.generated.tables.Role.RolePath; +import org.dependencytrack.persistence.jooq.generated.tables.User.UserPath; +import org.dependencytrack.persistence.jooq.generated.tables.records.UsersProjectsRolesRecord; +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Index; +import org.jooq.InverseForeignKey; +import org.jooq.Name; +import org.jooq.Path; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.Record; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class UsersProjectsRoles extends TableImpl { + + private static final long serialVersionUID = 622585294; + + /** + * The reference instance of USERS_PROJECTS_ROLES + */ + public static final UsersProjectsRoles USERS_PROJECTS_ROLES = new UsersProjectsRoles(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return UsersProjectsRolesRecord.class; + } + + /** + * The column USERS_PROJECTS_ROLES.USER_ID. + */ + public final TableField userId = createField(DSL.name("USER_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + /** + * The column USERS_PROJECTS_ROLES.PROJECT_ID. + */ + public final TableField projectId = createField(DSL.name("PROJECT_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + /** + * The column USERS_PROJECTS_ROLES.ROLE_ID. + */ + public final TableField roleId = createField(DSL.name("ROLE_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + private UsersProjectsRoles(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private UsersProjectsRoles(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased USERS_PROJECTS_ROLES table reference + */ + public UsersProjectsRoles(String alias) { + this(DSL.name(alias), USERS_PROJECTS_ROLES); + } + + /** + * Create an aliased USERS_PROJECTS_ROLES table reference + */ + public UsersProjectsRoles(Name alias) { + this(alias, USERS_PROJECTS_ROLES); + } + + /** + * Create a USERS_PROJECTS_ROLES table reference + */ + public UsersProjectsRoles() { + this(DSL.name("USERS_PROJECTS_ROLES"), null); + } + + public UsersProjectsRoles(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath, USERS_PROJECTS_ROLES); + } + + /** + * A subtype implementing {@link Path} for simplified path-based joins. + */ + @Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" + ) + public static class UsersProjectsRolesPath extends UsersProjectsRoles implements Path { + + private static final long serialVersionUID = 622585294; + public UsersProjectsRolesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath); + } + private UsersProjectsRolesPath(Name alias, Table aliased) { + super(alias, aliased); + } + + @Override + public UsersProjectsRolesPath as(String alias) { + return new UsersProjectsRolesPath(DSL.name(alias), this); + } + + @Override + public UsersProjectsRolesPath as(Name alias) { + return new UsersProjectsRolesPath(alias, this); + } + + @Override + public UsersProjectsRolesPath as(Table alias) { + return new UsersProjectsRolesPath(alias.getQualifiedName(), this); + } + } + + @Override + public Schema getSchema() { + return aliased() ? null : DefaultSchema.DEFAULT_SCHEMA; + } + + @Override + public List getIndexes() { + return Arrays.asList(Indexes.USERS_PROJECTS_ROLES_ROLE_ID_IDX, Indexes.USERS_PROJECTS_ROLES_USER_PROJECT_IDX); + } + + @Override + public List> getReferences() { + return Arrays.asList(Keys.USERS_PROJECTS_ROLES_PROJECT_FK, Keys.USERS_PROJECTS_ROLES_ROLE_FK, Keys.USERS_PROJECTS_ROLES_USER_FK); + } + + private transient ProjectPath _project; + + /** + * Get the implicit join path to the PROJECT table. + */ + public ProjectPath project() { + if (_project == null) + _project = new ProjectPath(this, Keys.USERS_PROJECTS_ROLES_PROJECT_FK, null); + + return _project; + } + + private transient RolePath _role; + + /** + * Get the implicit join path to the ROLE table. + */ + public RolePath role() { + if (_role == null) + _role = new RolePath(this, Keys.USERS_PROJECTS_ROLES_ROLE_FK, null); + + return _role; + } + + private transient UserPath _user; + + /** + * Get the implicit join path to the USER table. + */ + public UserPath user() { + if (_user == null) + _user = new UserPath(this, Keys.USERS_PROJECTS_ROLES_USER_FK, null); + + return _user; + } + + @Override + public UsersProjectsRoles as(String alias) { + return new UsersProjectsRoles(DSL.name(alias), this); + } + + @Override + public UsersProjectsRoles as(Name alias) { + return new UsersProjectsRoles(alias, this); + } + + @Override + public UsersProjectsRoles as(Table alias) { + return new UsersProjectsRoles(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public UsersProjectsRoles rename(String name) { + return new UsersProjectsRoles(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public UsersProjectsRoles rename(Name name) { + return new UsersProjectsRoles(name, null); + } + + /** + * Rename this table + */ + @Override + public UsersProjectsRoles rename(Table name) { + return new UsersProjectsRoles(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UsersProjectsRoles where(Condition condition) { + return new UsersProjectsRoles(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UsersProjectsRoles where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UsersProjectsRoles where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UsersProjectsRoles where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UsersProjectsRoles where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UsersProjectsRoles where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UsersProjectsRoles where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UsersProjectsRoles where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UsersProjectsRoles whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UsersProjectsRoles whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java index 9841c2aec4..06ebbc541f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersTeams extends TableImpl { - private static final long serialVersionUID = 666645532; + private static final long serialVersionUID = 274318204; /** * The reference instance of USERS_TEAMS @@ -116,13 +116,13 @@ public UsersTeams(Table path, ForeignKey { - private static final long serialVersionUID = 666645532; + private static final long serialVersionUID = 274318204; public UsersTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java index 5052c1de8e..df860ea400 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Vex extends TableImpl { - private static final long serialVersionUID = 1983143598; + private static final long serialVersionUID = -865420210; /** * The reference instance of VEX @@ -150,13 +150,13 @@ public Vex(Table path, ForeignKey childPath, value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class VexPath extends Vex implements Path { - private static final long serialVersionUID = 1983143598; + private static final long serialVersionUID = -865420210; public VexPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java index 67eb58b714..94a9914ec3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysis extends TableImpl { - private static final long serialVersionUID = -423138649; + private static final long serialVersionUID = 1089999461; /** * The reference instance of VIOLATIONANALYSIS @@ -141,13 +141,13 @@ public ViolationAnalysis(Table path, ForeignKey { - private static final long serialVersionUID = -423138649; + private static final long serialVersionUID = 1089999461; public ViolationAnalysisPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java index 39e8632b8a..4bbea6eeb3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysisComment extends TableImpl { - private static final long serialVersionUID = 312755086; + private static final long serialVersionUID = 833389648; /** * The reference instance of VIOLATIONANALYSISCOMMENT @@ -134,13 +134,13 @@ public ViolationAnalysisComment(Table path, ForeignKey { - private static final long serialVersionUID = 312755086; + private static final long serialVersionUID = 833389648; public ViolationAnalysisCommentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java index 4ef908ecb2..90d1c2acac 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilitiesTags extends TableImpl { - private static final long serialVersionUID = -28182264; + private static final long serialVersionUID = 1626926470; /** * The reference instance of VULNERABILITIES_TAGS @@ -116,13 +116,13 @@ public VulnerabilitiesTags(Table path, ForeignKey { - private static final long serialVersionUID = -28182264; + private static final long serialVersionUID = 1626926470; public VulnerabilitiesTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java index 5b351d5b03..43bf41e95d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java @@ -57,14 +57,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Vulnerability extends TableImpl { - private static final long serialVersionUID = 917592549; + private static final long serialVersionUID = 194354309; /** * The reference instance of VULNERABILITY @@ -274,13 +274,13 @@ public Vulnerability(Table path, ForeignKey { - private static final long serialVersionUID = 917592549; + private static final long serialVersionUID = 194354309; public VulnerabilityPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java index 7c2c54f1af..bc898db017 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityAlias extends TableImpl { - private static final long serialVersionUID = -1336625644; + private static final long serialVersionUID = 2010552213; /** * The reference instance of VULNERABILITYALIAS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java index f801f19636..0f076f367b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java @@ -38,14 +38,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityMetrics extends TableImpl { - private static final long serialVersionUID = 2050311223; + private static final long serialVersionUID = -1647962504; /** * The reference instance of VULNERABILITYMETRICS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java index 7437c2e904..d6c218b60e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicy extends TableImpl { - private static final long serialVersionUID = -1825956886; + private static final long serialVersionUID = -751906294; /** * The reference instance of VULNERABILITY_POLICY @@ -170,13 +170,13 @@ public VulnerabilityPolicy(Table path, ForeignKey { - private static final long serialVersionUID = -1825956886; + private static final long serialVersionUID = -751906294; public VulnerabilityPolicyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java index 76682410b3..823a2208db 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java @@ -38,14 +38,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicyBundle extends TableImpl { - private static final long serialVersionUID = 901187422; + private static final long serialVersionUID = -653983299; /** * The reference instance of VULNERABILITY_POLICY_BUNDLE diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java index 820c1e2538..042b62043d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java @@ -41,14 +41,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityScan extends TableImpl { - private static final long serialVersionUID = 1049459592; + private static final long serialVersionUID = 936592231; /** * The reference instance of VULNERABILITYSCAN diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java index 61af3c45fe..7f6b561bf8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftware extends TableImpl { - private static final long serialVersionUID = 1920414480; + private static final long serialVersionUID = 1199573646; /** * The reference instance of VULNERABLESOFTWARE @@ -245,13 +245,13 @@ public VulnerableSoftware(Table path, ForeignKey { - private static final long serialVersionUID = 1920414480; + private static final long serialVersionUID = 1199573646; public VulnerableSoftwarePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java index f1cfc22a25..476f3c573e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftwareVulnerabilities extends TableImpl { - private static final long serialVersionUID = -1138822448; + private static final long serialVersionUID = -587467024; /** * The reference instance of VULNERABLESOFTWARE_VULNERABILITIES @@ -121,13 +121,13 @@ public VulnerableSoftwareVulnerabilities(Table path, Forei value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) public static class VulnerableSoftwareVulnerabilitiesPath extends VulnerableSoftwareVulnerabilities implements Path { - private static final long serialVersionUID = -1138822448; + private static final long serialVersionUID = -587467024; public VulnerableSoftwareVulnerabilitiesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java index 370ea2b4a1..97dab01600 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java @@ -50,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class WorkflowState extends TableImpl { - private static final long serialVersionUID = -89590387; + private static final long serialVersionUID = 136710125; /** * The reference instance of WORKFLOW_STATE @@ -152,13 +152,13 @@ public WorkflowState(Table path, ForeignKey { - private static final long serialVersionUID = -89590387; + private static final long serialVersionUID = 136710125; public WorkflowStatePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java index b8b4a6e354..7d7ae2428d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AffectedVersionAttributionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1126582934; + private static final long serialVersionUID = 830189685; /** * Setter for AFFECTEDVERSIONATTRIBUTION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java index 7a822d980b..c387cdcb0e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AnalysisCommentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -197720386; + private static final long serialVersionUID = 683571869; /** * Setter for ANALYSISCOMMENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java index 9590189381..f72bc82c6f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AnalysisRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 374390912; + private static final long serialVersionUID = -1074618273; /** * Setter for ANALYSIS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java index 0b228ed09c..aef891db85 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKeyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1351723053; + private static final long serialVersionUID = -285420750; /** * Setter for APIKEY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java index 26a1b25d02..9b5a605556 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKeysTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1341969992; + private static final long serialVersionUID = -2091283289; /** * Setter for APIKEYS_TEAMS.TEAM_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java index 8b9b9d68bd..e1920895e7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class BomRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 2085004136; + private static final long serialVersionUID = -1158088535; /** * Setter for BOM.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java index 6a3e829afe..6ef69f9020 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentOccurrenceRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1231563309; + private static final long serialVersionUID = 1566639764; /** * Setter for COMPONENT_OCCURRENCE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java index feb67be319..2a261a2e3a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentPropertyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1838061987; + private static final long serialVersionUID = 1894747516; /** * Setter for COMPONENT_PROPERTY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java index f4c2cceee0..7043b48983 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 646377599; + private static final long serialVersionUID = -1813992192; /** * Setter for COMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java index c455b6709c..174c7519aa 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentsVulnerabilitiesRecord extends TableRecordImpl { - private static final long serialVersionUID = 1820783384; + private static final long serialVersionUID = 1782821111; /** * Setter for COMPONENTS_VULNERABILITIES.COMPONENT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java index 568a5ff348..1613d9b137 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ConfigPropertyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -64011058; + private static final long serialVersionUID = -1531833329; /** * Setter for CONFIGPROPERTY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java index 7a55a926e3..05ac2d25c7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class DependencyMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -80477003; + private static final long serialVersionUID = -78726026; /** * Setter for DEPENDENCYMETRICS.COMPONENT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java index dff2fdd06e..023facaf15 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class EpssRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1886755905; + private static final long serialVersionUID = 1881018208; /** * Setter for EPSS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java index 9e6b707bd4..ceb7e1d5b9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class FindingAttributionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 2086301322; + private static final long serialVersionUID = -1597754647; /** * Setter for FINDINGATTRIBUTION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java index 18841bb392..89084b52c3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityAnalysisRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1337559277; + private static final long serialVersionUID = 1886133780; /** * Setter for INTEGRITY_ANALYSIS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java index 938b5f76d5..9b181b743c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityMetaComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 527104531; + private static final long serialVersionUID = -2144778894; /** * Setter for INTEGRITY_META_COMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java index bb0550f09e..e036f8f951 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroupLicenseRecord extends TableRecordImpl { - private static final long serialVersionUID = -1265959473; + private static final long serialVersionUID = -449692016; /** * Setter for LICENSEGROUP_LICENSE.LICENSEGROUP_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java index fdb63bf30f..baa58c753f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1789324508; + private static final long serialVersionUID = -2014332549; /** * Setter for LICENSEGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java index 294fe56469..83661cb1f8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1355749591; + private static final long serialVersionUID = -108552760; /** * Setter for LICENSE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java index 4a6cc5d677..ed8bf95d18 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedLdapGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 749583562; + private static final long serialVersionUID = 1055111209; /** * Setter for MAPPEDLDAPGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java index a2baf9b6da..7ec4319b08 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedOidcGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1346971408; + private static final long serialVersionUID = -235246095; /** * Setter for MAPPEDOIDCGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java index 36b0322cfa..64e4242d48 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationPublisherRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 421461737; + private static final long serialVersionUID = -140065302; /** * Setter for NOTIFICATIONPUBLISHER.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java index ed9162de8d..e1efa0e115 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleProjectsRecord extends TableRecordImpl { - private static final long serialVersionUID = -777335568; + private static final long serialVersionUID = -458610639; /** * Setter for NOTIFICATIONRULE_PROJECTS.NOTIFICATIONRULE_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java index cf29438383..219d6fad16 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1476520370; + private static final long serialVersionUID = -1490850195; /** * Setter for NOTIFICATIONRULE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java index 25ed443f5c..c2b8f14a05 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1533227447; + private static final long serialVersionUID = 2128918538; /** * Setter for NOTIFICATIONRULE_TAGS.NOTIFICATIONRULE_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java index 9e69cb31ec..fde1d95331 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 932661529; + private static final long serialVersionUID = 631633464; /** * Setter for NOTIFICATIONRULE_TEAMS.NOTIFICATIONRULE_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java index 41fbd7e904..26146fc65f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class OidcGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 669539251; + private static final long serialVersionUID = -1380876876; /** * Setter for OIDCGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java index 4295af365b..ba13280d95 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PermissionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -421305018; + private static final long serialVersionUID = 1586304711; /** * Setter for PERMISSION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java index 3d66ca8fe0..fcbf737aca 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyConditionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1810267312; + private static final long serialVersionUID = 1855718319; /** * Setter for POLICYCONDITION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java index c71df47a21..a864d6911c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyProjectsRecord extends TableRecordImpl { - private static final long serialVersionUID = 1024547152; + private static final long serialVersionUID = 1289508177; /** * Setter for POLICY_PROJECTS.POLICY_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java index af30c99572..96d0d3311a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 54002621; + private static final long serialVersionUID = -1255213442; /** * Setter for POLICY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java index fbd355ac64..4db995d17f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1568348211; + private static final long serialVersionUID = -718175564; /** * Setter for POLICY_TAGS.POLICY_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java index c43e65dec2..9fa503fbea 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyViolationRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 731228325; + private static final long serialVersionUID = -2130877628; /** * Setter for POLICYVIOLATION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java index 9577078b7b..5a4a758dbc 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PortfolioMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1414503296; + private static final long serialVersionUID = -640386303; /** * Setter for PORTFOLIOMETRICS.COMPONENTS. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java index 53fcfc3dc8..fc2c868a54 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectAccessTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -519805377; + private static final long serialVersionUID = -1036749248; /** * Setter for PROJECT_ACCESS_TEAMS.PROJECT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java index fc138a4ae4..400af2fd9e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectHierarchyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -71539204; + private static final long serialVersionUID = -407800101; /** * Setter for PROJECT_HIERARCHY.PARENT_PROJECT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java index 77a0306f27..638a3418c9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetadataRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1834903502; + private static final long serialVersionUID = -462682031; /** * Setter for PROJECT_METADATA.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java index a294e097e4..bc05e10987 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 404466563; + private static final long serialVersionUID = 492620514; /** * Setter for PROJECTMETRICS.COMPONENTS. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java index 69d8d332a4..ae353606f7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectPropertyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -433467356; + private static final long serialVersionUID = 145578597; /** * Setter for PROJECT_PROPERTY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java index 07af161ca7..18e45539ac 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java @@ -22,14 +22,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 231035541; + private static final long serialVersionUID = 1640806964; /** * Setter for PROJECT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java index 11541e63b4..46ac5702e7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectsTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 811696502; + private static final long serialVersionUID = 1673410517; /** * Setter for PROJECTS_TAGS.TAG_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java index ab94228cbd..65dedc05e2 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RepositoryMetaComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -2012991409; + private static final long serialVersionUID = 530816784; /** * Setter for REPOSITORY_META_COMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java index db3b0d3cc2..df9f7ae905 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RepositoryRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1560456737; + private static final long serialVersionUID = 193876256; /** * Setter for REPOSITORY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java new file mode 100644 index 0000000000..6dbc946de9 --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java @@ -0,0 +1,108 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables.records; + + +import java.util.UUID; + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.tables.Role; +import org.jooq.Record1; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class RoleRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = -404691591; + + /** + * Setter for ROLE.ID. + */ + public RoleRecord setId(Long value) { + set(0, value); + return this; + } + + /** + * Getter for ROLE.ID. + */ + public Long getId() { + return (Long) get(0); + } + + /** + * Setter for ROLE.NAME. + */ + public RoleRecord setName(String value) { + set(1, value); + return this; + } + + /** + * Getter for ROLE.NAME. + */ + public String getName() { + return (String) get(1); + } + + /** + * Setter for ROLE.UUID. + */ + public RoleRecord setUuid(UUID value) { + set(2, value); + return this; + } + + /** + * Getter for ROLE.UUID. + */ + public UUID getUuid() { + return (UUID) get(2); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached RoleRecord + */ + public RoleRecord() { + super(Role.ROLE); + } + + /** + * Create a detached, initialised RoleRecord + */ + public RoleRecord(Long id, String name, UUID uuid) { + super(Role.ROLE); + + setId(id); + setName(name); + setUuid(uuid); + resetTouchedOnNotNull(); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java new file mode 100644 index 0000000000..26f33eff91 --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java @@ -0,0 +1,80 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables.records; + + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions; +import org.jooq.impl.TableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class RolesPermissionsRecord extends TableRecordImpl { + + private static final long serialVersionUID = -268299302; + + /** + * Setter for ROLES_PERMISSIONS.ROLE_ID. + */ + public RolesPermissionsRecord setRoleId(Long value) { + set(0, value); + return this; + } + + /** + * Getter for ROLES_PERMISSIONS.ROLE_ID. + */ + public Long getRoleId() { + return (Long) get(0); + } + + /** + * Setter for ROLES_PERMISSIONS.PERMISSION_ID. + */ + public RolesPermissionsRecord setPermissionId(Long value) { + set(1, value); + return this; + } + + /** + * Getter for ROLES_PERMISSIONS.PERMISSION_ID. + */ + public Long getPermissionId() { + return (Long) get(1); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached RolesPermissionsRecord + */ + public RolesPermissionsRecord() { + super(RolesPermissions.ROLES_PERMISSIONS); + } + + /** + * Create a detached, initialised RolesPermissionsRecord + */ + public RolesPermissionsRecord(Long roleId, Long permissionId) { + super(RolesPermissions.ROLES_PERMISSIONS); + + setRoleId(roleId); + setPermissionId(permissionId); + resetTouchedOnNotNull(); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java index 166f000630..f1a1bfa12f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1569362453; + private static final long serialVersionUID = -313015124; /** * Setter for SERVICECOMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java index 7fdea3f93a..e80071bfc7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponentsVulnerabilitiesRecord extends TableRecordImpl { - private static final long serialVersionUID = -1485690636; + private static final long serialVersionUID = -1453803659; /** * Setter for diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java index 6a7b91b02e..2c80cafc04 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TagRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -340989787; + private static final long serialVersionUID = -1486904060; /** * Setter for TAG.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java index c83f500137..d7ae92976b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TeamRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -838322539; + private static final long serialVersionUID = 1435240628; /** * Setter for TEAM.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java index 7425f770c9..a87f56dd76 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TeamsPermissionsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1287233552; + private static final long serialVersionUID = 1282451951; /** * Setter for TEAMS_PERMISSIONS.TEAM_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java index 08554da176..dfad702be8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UserProjectEffectivePermissionsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 367791318; + private static final long serialVersionUID = -934414569; /** * Setter for USER_PROJECT_EFFECTIVE_PERMISSIONS.PROJECT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java index 07f7a718b5..ffe1e818ef 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UserRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 2060697873; + private static final long serialVersionUID = -1987326126; /** * Setter for USER.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java index ab8d54e08e..49b4bcd603 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersPermissionsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1186764856; + private static final long serialVersionUID = -1191546457; /** * Setter for USERS_PERMISSIONS.USER_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersProjectsRolesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersProjectsRolesRecord.java new file mode 100644 index 0000000000..ff32879bcf --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersProjectsRolesRecord.java @@ -0,0 +1,96 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables.records; + + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; +import org.jooq.impl.TableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-27" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class UsersProjectsRolesRecord extends TableRecordImpl { + + private static final long serialVersionUID = -147063056; + + /** + * Setter for USERS_PROJECTS_ROLES.USER_ID. + */ + public UsersProjectsRolesRecord setUserId(Long value) { + set(0, value); + return this; + } + + /** + * Getter for USERS_PROJECTS_ROLES.USER_ID. + */ + public Long getUserId() { + return (Long) get(0); + } + + /** + * Setter for USERS_PROJECTS_ROLES.PROJECT_ID. + */ + public UsersProjectsRolesRecord setProjectId(Long value) { + set(1, value); + return this; + } + + /** + * Getter for USERS_PROJECTS_ROLES.PROJECT_ID. + */ + public Long getProjectId() { + return (Long) get(1); + } + + /** + * Setter for USERS_PROJECTS_ROLES.ROLE_ID. + */ + public UsersProjectsRolesRecord setRoleId(Long value) { + set(2, value); + return this; + } + + /** + * Getter for USERS_PROJECTS_ROLES.ROLE_ID. + */ + public Long getRoleId() { + return (Long) get(2); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached UsersProjectsRolesRecord + */ + public UsersProjectsRolesRecord() { + super(UsersProjectsRoles.USERS_PROJECTS_ROLES); + } + + /** + * Create a detached, initialised UsersProjectsRolesRecord + */ + public UsersProjectsRolesRecord(Long userId, Long projectId, Long roleId) { + super(UsersProjectsRoles.USERS_PROJECTS_ROLES); + + setUserId(userId); + setProjectId(projectId); + setRoleId(roleId); + resetTouchedOnNotNull(); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java index 1dd4d223c0..8b04fc466e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -931364464; + private static final long serialVersionUID = -800688593; /** * Setter for USERS_TEAMS.USER_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java index dcd843a465..8e72850505 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VexRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1950410703; + private static final long serialVersionUID = 656810192; /** * Setter for VEX.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java index ea472bc731..9f9a7df49d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysisCommentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1514790873; + private static final long serialVersionUID = 392460294; /** * Setter for VIOLATIONANALYSISCOMMENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java index 6fe7fe6651..839867fd5c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysisRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -706529884; + private static final long serialVersionUID = 1891849923; /** * Setter for VIOLATIONANALYSIS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java index ec4ca69345..8942679101 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilitiesTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1310036997; + private static final long serialVersionUID = 822864282; /** * Setter for VULNERABILITIES_TAGS.TAG_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java index f361662de5..6009c692f9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityAliasRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -104244075; + private static final long serialVersionUID = -1497308906; /** * Setter for VULNERABILITYALIAS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java index d4b5a1f8ba..6fa5df32a3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1501402685; + private static final long serialVersionUID = 336038556; /** * Setter for VULNERABILITYMETRICS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java index e6a812d7ff..5e135259c6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicyBundleRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1296169560; + private static final long serialVersionUID = -1375266263; /** * Setter for VULNERABILITY_POLICY_BUNDLE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java index e17eb333b1..1d2efcb45e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1607234685; + private static final long serialVersionUID = 1120893212; /** * Setter for VULNERABILITY_POLICY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java index 3dd02e8dfd..04072978c9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -232753684; + private static final long serialVersionUID = 1739870155; /** * Setter for VULNERABILITY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java index de93c263ea..a94a8bece1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityScanRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1717386480; + private static final long serialVersionUID = 147284591; /** * Setter for VULNERABILITYSCAN.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java index ed33346553..7f8e29a080 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftwareRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 925913319; + private static final long serialVersionUID = 638654342; /** * Setter for VULNERABLESOFTWARE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java index 7e1e9d1634..f4ab34c9d1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftwareVulnerabilitiesRecord extends TableRecordImpl { - private static final long serialVersionUID = -1050450335; + private static final long serialVersionUID = -1792385758; /** * Setter for diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java index 14e167da5a..8974817812 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-26" + "schema version:v5.6.0-27" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class WorkflowStateRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -785742106; + private static final long serialVersionUID = 1804473797; /** * Setter for WORKFLOW_STATE.ID. diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index e9ec54a4fd..d80df826f3 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -1189,22 +1189,6 @@
- - 9:75a5b859b6131f15a841804da10c14dc - - - SET CONSTRAINTS ALL IMMEDIATE - CREATE OR REPLACE FUNCTION remove_duplicate_rows( table_name TEXT, @@ -1258,6 +1242,8 @@ PERFORM remove_duplicate_rows('TEAMS_PERMISSIONS', 'TEAM_ID', 'PERMISSION_ID'); END $$; + + DROP FUNCTION remove_duplicate_rows; @@ -1280,7 +1266,7 @@ -- Loop over each team name group that has duplicates. FOR rec IN SELECT - "NAME" AS name, + "NAME", MIN("ID") AS canonical_id, ARRAY_AGG("ID") AS all_ids FROM "TEAM" @@ -1314,14 +1300,6 @@ $delete$, dup_id); END LOOP; END LOOP; - - PERFORM remove_duplicate_rows('APIKEYS_TEAMS', 'TEAM_ID', 'APIKEY_ID'); - PERFORM remove_duplicate_rows('LDAPUSERS_TEAMS', 'TEAM_ID', 'LDAPUSER_ID'); - PERFORM remove_duplicate_rows('MANAGEDUSERS_TEAMS', 'TEAM_ID', 'MANAGEDUSER_ID'); - PERFORM remove_duplicate_rows('NOTIFICATIONRULE_TEAMS', 'NOTIFICATIONRULE_ID', 'TEAM_ID'); - PERFORM remove_duplicate_rows('OIDCUSERS_TEAMS', 'TEAM_ID', 'OIDCUSERS_ID'); - PERFORM remove_duplicate_rows('TEAMS_PERMISSIONS', 'TEAM_ID', 'PERMISSION_ID'); - DROP FUNCTION remove_duplicate_rows; END $$; @@ -1454,15 +1432,6 @@ - - 9:aa6e0cecae0b4f050a56eb1bbcb686be - @@ -1635,17 +1604,8 @@ - WITH cte_created_user AS ( - INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "DN") - SELECT 'LDAP', "USERNAME", "EMAIL", "DN" - FROM "LDAPUSER" - ON CONFLICT ("USERNAME") DO NOTHING - RETURNING "USERNAME" - ) INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "DN") - SELECT 'LDAP', ("USERNAME" || '-CONFLICT-LDAP') AS "USERNAME", "EMAIL", "DN" - FROM "LDAPUSER" - WHERE "USERNAME" NOT IN (SELECT "USERNAME" FROM cte_created_user); + SELECT 'LDAP', "USERNAME", "EMAIL", "DN" FROM "LDAPUSER"; INSERT INTO "USERS_PERMISSIONS" ("PERMISSION_ID", "USER_ID") SELECT "LDAPUSERS_PERMISSIONS"."PERMISSION_ID" @@ -1654,8 +1614,7 @@ INNER JOIN "LDAPUSER" ON "LDAPUSER"."ID" = "LDAPUSERS_PERMISSIONS"."LDAPUSER_ID" INNER JOIN "USER" - ON ("USER"."USERNAME" = "LDAPUSER"."USERNAME" - OR "USER"."USERNAME" = ("LDAPUSER"."USERNAME" || '-CONFLICT-LDAP')) + ON "USER"."USERNAME" = "LDAPUSER"."USERNAME" AND "USER"."TYPE" = 'LDAP' ON CONFLICT ("PERMISSION_ID", "USER_ID") DO NOTHING; @@ -1666,25 +1625,15 @@ INNER JOIN "LDAPUSER" ON "LDAPUSER"."ID" = "LDAPUSERS_TEAMS"."LDAPUSER_ID" INNER JOIN "USER" - ON ("USER"."USERNAME" = "LDAPUSER"."USERNAME" - OR "USER"."USERNAME" = ("LDAPUSER"."USERNAME" || '-CONFLICT-LDAP')) + ON "USER"."USERNAME" = "LDAPUSER"."USERNAME" AND "USER"."TYPE" = 'LDAP' ON CONFLICT ("TEAM_ID", "USER_ID") DO NOTHING; - WITH cte_created_user AS ( - INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER") - SELECT 'OIDC', "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER" - FROM "OIDCUSER" - ON CONFLICT ("USERNAME") DO NOTHING - RETURNING "USERNAME" - ) INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER") - SELECT 'OIDC', ("USERNAME" || '-CONFLICT-OIDC') AS "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER" - FROM "OIDCUSER" - WHERE "USERNAME" NOT IN (SELECT "USERNAME" FROM cte_created_user); + SELECT 'OIDC', "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER" FROM "OIDCUSER"; INSERT INTO "USERS_PERMISSIONS" ("PERMISSION_ID", "USER_ID") SELECT "OIDCUSERS_PERMISSIONS"."PERMISSION_ID" @@ -1693,8 +1642,7 @@ INNER JOIN "OIDCUSER" ON "OIDCUSER"."ID" = "OIDCUSERS_PERMISSIONS"."OIDCUSER_ID" INNER JOIN "USER" - ON ("USER"."USERNAME" = "OIDCUSER"."USERNAME" - OR "USER"."USERNAME" = ("OIDCUSER"."USERNAME" || '-CONFLICT-OIDC')) + ON "USER"."USERNAME" = "OIDCUSER"."USERNAME" AND "USER"."TYPE" = 'OIDC' ON CONFLICT ("PERMISSION_ID", "USER_ID") DO NOTHING; @@ -1705,8 +1653,7 @@ INNER JOIN "OIDCUSER" ON "OIDCUSER"."ID" = "OIDCUSERS_TEAMS"."OIDCUSERS_ID" INNER JOIN "USER" - ON ("USER"."USERNAME" = "OIDCUSER"."USERNAME" - OR "USER"."USERNAME" = ("OIDCUSER"."USERNAME" || '-CONFLICT-OIDC')) + ON "USER"."USERNAME" = "OIDCUSER"."USERNAME" AND "USER"."TYPE" = 'OIDC' ON CONFLICT ("TEAM_ID", "USER_ID") DO NOTHING; diff --git a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java deleted file mode 100644 index d8845a8b75..0000000000 --- a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.persistence; - -import alpine.Config; -import alpine.common.logging.Logger; -import alpine.model.ConfigProperty; -import alpine.model.ManagedUser; -import alpine.model.Permission; -import alpine.model.Team; -import alpine.server.auth.PasswordService; -import jakarta.servlet.ServletContextEvent; -import jakarta.servlet.ServletContextListener; -import org.dependencytrack.auth.Permissions; -import org.dependencytrack.common.ConfigKey; -import org.dependencytrack.model.ConfigPropertyConstants; -import org.dependencytrack.model.License; -import org.dependencytrack.model.RepositoryType; -import org.dependencytrack.parser.spdx.json.SpdxLicenseDetailParser; -import org.dependencytrack.persistence.defaults.DefaultLicenseGroupImporter; -import org.dependencytrack.util.NotificationUtil; -import org.dependencytrack.util.WaitingLockConfiguration; - -import java.io.IOException; -import java.time.Duration; -import java.time.Instant; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -import static net.javacrumbs.shedlock.core.LockAssert.assertLocked; -import static org.dependencytrack.model.ConfigPropertyConstants.INTERNAL_DEFAULT_OBJECTS_VERSION; -import static org.dependencytrack.util.LockProvider.executeWithLockWaiting; - -/** - * Creates default objects on an empty database. - * - * @author Steve Springett - * @since 3.0.0 - */ -public class DefaultObjectGenerator implements ServletContextListener { - - private static final Logger LOGGER = Logger.getLogger(DefaultObjectGenerator.class); - private static final Map PERMISSIONS_MAP = new HashMap<>(); - - private static final Map> DEFAULT_TEAM_PERMISSIONS = Map.of( - "Administrators", Stream.of(Permissions.values()) - .map(Permissions::name) - .toList(), - "Portfolio Managers", List.of( - Permissions.Constants.VIEW_PORTFOLIO, - Permissions.Constants.PORTFOLIO_MANAGEMENT, - Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE, - Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, - Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE, - Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE), - "Automation", List.of( - Permissions.Constants.VIEW_PORTFOLIO, - Permissions.Constants.BOM_UPLOAD), - "Badge Viewers", List.of( - Permissions.Constants.VIEW_BADGES)); - - private static final Map> DEFAULT_ROLE_PERMISSIONS = Map.of( - "Project Admin", List.of( - Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE, - Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, - Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE, - Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE, - Permissions.Constants.VULNERABILITY_ANALYSIS, - Permissions.Constants.VULNERABILITY_ANALYSIS_CREATE, - Permissions.Constants.VULNERABILITY_ANALYSIS_READ, - Permissions.Constants.VULNERABILITY_ANALYSIS_UPDATE, - Permissions.Constants.POLICY_MANAGEMENT, - Permissions.Constants.POLICY_MANAGEMENT_CREATE, - Permissions.Constants.POLICY_MANAGEMENT_READ, - Permissions.Constants.POLICY_MANAGEMENT_UPDATE, - Permissions.Constants.POLICY_MANAGEMENT_DELETE), - "Project Auditor", List.of( - Permissions.Constants.VIEW_PORTFOLIO, - Permissions.Constants.VIEW_VULNERABILITY, - Permissions.Constants.VIEW_POLICY_VIOLATION, - Permissions.Constants.VULNERABILITY_ANALYSIS_READ), - "Project Editor", List.of( - Permissions.Constants.BOM_UPLOAD, - Permissions.Constants.VIEW_PORTFOLIO, - Permissions.Constants.PORTFOLIO_MANAGEMENT_READ, - Permissions.Constants.VIEW_VULNERABILITY, - Permissions.Constants.VULNERABILITY_ANALYSIS_READ, - Permissions.Constants.PROJECT_CREATION_UPLOAD), - "Project Viewer", List.of( - Permissions.Constants.VIEW_PORTFOLIO, - Permissions.Constants.VIEW_VULNERABILITY, - Permissions.Constants.VIEW_BADGES)); - - /** - * {@inheritDoc} - */ - @Override - public void contextInitialized(final ServletContextEvent event) { - if (!Config.getInstance().getPropertyAsBoolean(ConfigKey.INIT_TASKS_ENABLED)) { - LOGGER.info("Not populating database with default objects because %s is disabled" - .formatted(ConfigKey.INIT_TASKS_ENABLED.getPropertyName())); - return; - } - - // Ensure that this task is only executed by a single instance at once. - // Wait for lock acquisition rather than simply skipping execution, - // since application logic may depend on default objects being present. - final var lockConfig = new WaitingLockConfiguration( - /* createdAt */ Instant.now(), - /* name */ getClass().getName(), - /* lockAtMostFor */ Duration.ofMinutes(5), - /* lockAtLeastFor */ Duration.ZERO, - /* pollInterval */ Duration.ofSeconds(1), - /* waitTimeout */ Duration.ofMinutes(5) - ); - - try { - executeWithLockWaiting(lockConfig, this::executeLocked); - } catch (Throwable t) { - if (Config.getInstance().getPropertyAsBoolean(ConfigKey.INIT_AND_EXIT)) { - // Make absolutely sure that we exit with non-zero code so - // the container orchestrator knows to restart the container. - LOGGER.error("Failed to populate database with default objects", t); - System.exit(1); - } - - throw new RuntimeException("Failed to populate database with default objects", t); - } - - if (Config.getInstance().getPropertyAsBoolean(ConfigKey.INIT_AND_EXIT)) { - LOGGER.info("Exiting because %s is enabled".formatted(ConfigKey.INIT_AND_EXIT.getPropertyName())); - System.exit(0); - } - } - - private void executeLocked() { - assertLocked(); - - if (!shouldExecute()) { - LOGGER.info("Default objects already populated for build %s (timestamp: %s); Skipping".formatted( - Config.getInstance().getApplicationBuildUuid(), - Config.getInstance().getApplicationBuildTimestamp() - )); - return; - } - - // TODO: Make population transactional with recordDefaultObjectsVersion(). - - LOGGER.info("Initializing default object generator"); - try (final var qm = new QueryManager()) { - loadDefaultPermissions(qm); - loadDefaultPersonas(qm); - loadDefaultLicenses(qm); - loadDefaultLicenseGroups(qm); - loadDefaultRepositories(qm); - loadDefaultRoles(qm); - loadDefaultConfigProperties(qm); - loadDefaultNotificationPublishers(qm); - recordDefaultObjectsVersion(qm); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void contextDestroyed(final ServletContextEvent event) { - /* Intentionally blank to satisfy interface */ - } - - private boolean shouldExecute() { - try (final var qm = new QueryManager()) { - final ConfigProperty configProperty = qm.getConfigProperty( - INTERNAL_DEFAULT_OBJECTS_VERSION.getGroupName(), - INTERNAL_DEFAULT_OBJECTS_VERSION.getPropertyName() - ); - - return configProperty == null - || configProperty.getPropertyValue() == null - || !Config.getInstance().getApplicationBuildUuid().equals(configProperty.getPropertyValue()); - } - } - - private void recordDefaultObjectsVersion() { - try (final var qm = new QueryManager()) { - qm.runInTransaction(() -> { - final ConfigProperty configProperty = qm.getConfigProperty( - INTERNAL_DEFAULT_OBJECTS_VERSION.getGroupName(), - INTERNAL_DEFAULT_OBJECTS_VERSION.getPropertyName() - ); - - configProperty.setPropertyValue(Config.getInstance().getApplicationBuildUuid()); - }); - } - } - - /** - * Loads the default licenses into the database if no license data exists. - */ - public static void loadDefaultLicenses() { - try (QueryManager qm = new QueryManager()) { - LOGGER.info("Synchronizing SPDX license definitions to datastore"); - - final SpdxLicenseDetailParser parser = new SpdxLicenseDetailParser(); - try { - final List licenses = parser.getLicenseDefinitions(); - for (final License license : licenses) { - LOGGER.debug("Synchronizing: " + license.getName()); - qm.synchronizeLicense(license, false); - } - } catch (IOException e) { - LOGGER.error("An error occurred during the parsing SPDX license definitions"); - LOGGER.error(e.getMessage()); - } - } - } - - /** - * Loads the default license groups into the database if no license groups exists. - */ - private void loadDefaultLicenseGroups() { - try (QueryManager qm = new QueryManager()) { - final DefaultLicenseGroupImporter importer = new DefaultLicenseGroupImporter(qm); - if (! importer.shouldImport()) { - return; - } - LOGGER.info("Adding default license group definitions to datastore"); - try { - importer.loadDefaults(); - } catch (IOException e) { - LOGGER.error("An error occurred loading default license group definitions"); - LOGGER.error(e.getMessage()); - } - } - } - - /** - * Loads the default permissions - */ - private void loadDefaultPermissions(final QueryManager qm) { - LOGGER.info("Synchronizing permissions to datastore"); - - List existing = Objects.requireNonNullElse(qm.getPermissions(), Collections.emptyList()) - .stream() - .map(Permission::getName) - .toList(); - - for (final Permissions value : Permissions.values()) - if (!existing.contains(value.name())) { - LOGGER.debug("Creating permission: " + value.name()); - PERMISSIONS_MAP.put(value.name(), qm.createPermission(value.name(), value.getDescription())); - } - } - - @SuppressWarnings("unused") - private void loadDefaultPersonas() { - try (final var qm = new QueryManager()) { - loadDefaultPersonas(qm); - } - } - - /** - * Loads the default users and teams - */ - private void loadDefaultPersonas() { - try (QueryManager qm = new QueryManager()) { - if (!qm.getManagedUsers().isEmpty() && !qm.getTeams().isEmpty()) { - return; - } - LOGGER.info("Adding default users and teams to datastore"); - LOGGER.debug("Creating user: admin"); - ManagedUser admin = qm.createManagedUser("admin", "Administrator", "admin@localhost", - new String(PasswordService.createHash("admin".toCharArray())), true, true, false); - - LOGGER.info("Adding default users and teams to datastore"); - - LOGGER.debug("Creating user: admin"); - ManagedUser admin = qm.createManagedUser("admin", "Administrator", "admin@localhost", - new String(PasswordService.createHash("admin".toCharArray())), true, true, false); - - for (var name : new String[] { "Administrators", "Portfolio Managers", "Automation", "Badge Viewers" }) { - LOGGER.debug("Creating team: " + name); - var team = qm.createTeam(name); - - LOGGER.debug("Assigning default permissions for team: " + name); - team.setPermissions(getPermissionsByName(DEFAULT_TEAM_PERMISSIONS.get(name))); - - qm.persist(team); - } - - LOGGER.debug("Assigning default permissions to teams"); - sysadmins.setPermissions(fullList); - managers.setPermissions(getPortfolioManagersPermissions(fullList)); - automation.setPermissions(getAutomationPermissions(fullList)); - badges.setPermissions(getBadgesPermissions(fullList)); - - qm.persist(sysadmins); - qm.persist(managers); - qm.persist(automation); - qm.persist(badges); - - LOGGER.debug("Adding admin user to System Administrators"); - qm.addUserToTeam(admin, sysadmins); - - admin = qm.getObjectById(ManagedUser.class, admin.getId()); - admin.setPermissions(qm.getPermissions()); - qm.persist(admin); - } - } - - /** - * Loads the default repositories - */ - private List getPermissionsByName(List names) { - return names.stream().map(PERMISSIONS_MAP::get).filter(Objects::nonNull).toList(); - } - - /** - * Loads the default Roles - */ - private void loadDefaultRoles(final QueryManager qm) { - if (!qm.getRoles().isEmpty()) - return; - - LOGGER.info("Adding default roles to datastore"); - - for (var name : new String[] { "Project Admin", "Project Auditor", "Project Editor", "Project Viewer" }) { - LOGGER.debug("Creating role: " + name); - qm.createRole(name, getPermissionsByName(DEFAULT_ROLE_PERMISSIONS.get(name))); - } - } - - public void loadDefaultRepositories() { - try (QueryManager qm = new QueryManager()) { - LOGGER.info("Synchronizing default repositories to datastore"); - qm.createRepository(RepositoryType.CPAN, "cpan-public-registry", "https://fastapi.metacpan.org/v1/", true, false, false, null, null); - qm.createRepository(RepositoryType.GEM, "rubygems.org", "https://rubygems.org/", true, false, false,null, null); - qm.createRepository(RepositoryType.HEX, "hex.pm", "https://hex.pm/", true, false, false, null, null); - qm.createRepository(RepositoryType.MAVEN, "central", "https://repo1.maven.org/maven2/", true, false, false, null, null); - qm.createRepository(RepositoryType.MAVEN, "atlassian-public", "https://packages.atlassian.com/content/repositories/atlassian-public/", true, false, false, null, null); - qm.createRepository(RepositoryType.MAVEN, "jboss-releases", "https://repository.jboss.org/nexus/content/repositories/releases/", true, false, false, null, null); - qm.createRepository(RepositoryType.MAVEN, "clojars", "https://repo.clojars.org/", true, false, false, null, null); - qm.createRepository(RepositoryType.MAVEN, "google-android", "https://maven.google.com/", true, false, false, null, null); - qm.createRepository(RepositoryType.NPM, "npm-public-registry", "https://registry.npmjs.org/", true, false, false, null, null); - qm.createRepository(RepositoryType.PYPI, "pypi.org", "https://pypi.org/", true, false, false, null, null); - qm.createRepository(RepositoryType.NUGET, "nuget-gallery", "https://api.nuget.org/", true, false, false, null, null); - qm.createRepository(RepositoryType.COMPOSER, "packagist", "https://repo.packagist.org/", true, false, false, null, null); - qm.createRepository(RepositoryType.CARGO, "crates.io", "https://crates.io", true, false, false, null, null); - qm.createRepository(RepositoryType.GO_MODULES, "proxy.golang.org", "https://proxy.golang.org", true, false, false, null, null); - qm.createRepository(RepositoryType.GITHUB, "github.com", "https://github.com", true, false, false, null, null); - qm.createRepository(RepositoryType.HACKAGE, "hackage.haskell", "https://hackage.haskell.org/", true, false, false, null, null); - qm.createRepository(RepositoryType.NIXPKGS, "nixos.org", "https://channels.nixos.org/nixpkgs-unstable/packages.json.br", true, false, false, null, null); - } - } - - /** - * Loads the default ConfigProperty objects - */ - private void loadDefaultConfigProperties() { - try (QueryManager qm = new QueryManager()) { - LOGGER.info("Synchronizing config properties to datastore"); - for (final ConfigPropertyConstants cpc : ConfigPropertyConstants.values()) { - LOGGER.debug("Creating config property: " + cpc.getGroupName() + " / " + cpc.getPropertyName()); - if (qm.getConfigProperty(cpc.getGroupName(), cpc.getPropertyName()) == null) { - qm.createConfigProperty(cpc.getGroupName(), cpc.getPropertyName(), cpc.getDefaultPropertyValue(), cpc.getPropertyType(), cpc.getDescription()); - } - } - } - } - - /** - * Loads the default notification publishers - */ - public void loadDefaultNotificationPublishers() { - try (QueryManager qm = new QueryManager()) { - LOGGER.info("Synchronizing notification publishers to datastore"); - try { - NotificationUtil.loadDefaultNotificationPublishers(qm); - } catch (IOException e) { - LOGGER.error("An error occurred while synchronizing a default notification publisher", e); - } - } - } -} diff --git a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java deleted file mode 100644 index 437a25e2d0..0000000000 --- a/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.persistence; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.jdo.PersistenceManager; -import javax.jdo.Query; - -import org.dependencytrack.model.Project; -import org.dependencytrack.model.Role; -import org.dependencytrack.model.ProjectRole; -import org.dependencytrack.persistence.jdbi.JdbiFactory; -import org.dependencytrack.persistence.jdbi.RoleDao; - -import alpine.common.logging.Logger; -import alpine.model.LdapUser; -import alpine.model.ManagedUser; -import alpine.model.OidcUser; -import alpine.model.Permission; -import alpine.model.UserPrincipal; -import alpine.resources.AlpineRequest; - -final class RoleQueryManager extends QueryManager implements IQueryManager { - - /** - * Represents a row returned by the USER_PROJECT_EFFECTIVE_PERMISSIONS view. - * - * @since 5.6.0 - */ - public record UserProjectEffectivePermissionsRow( - Long ldapUserId, - Long managedUserId, - Long oidcUserId, - Long projectId, - Long permissionId, - String permissionName) { - } - - private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); - - RoleQueryManager(final PersistenceManager pm) { - super(pm); - } - - RoleQueryManager(final PersistenceManager pm, final AlpineRequest request) { - super(pm, request); - } - - @Override - public Role createRole(final String name, final List permissions) { - return callInTransaction(() -> { - final Role role = new Role(); - role.setName(name); - role.setPermissions(Set.copyOf(permissions)); - - return persist(role); - }); - } - - @Override - public List getRoles() { - final Query query = pm.newQuery(Role.class); - if (orderBy == null) - query.setOrdering("name asc"); - - return query.executeList(); - } - - @Override - public Role getRole(final String uuid) { - return getObjectByUuid(Role.class, uuid, Role.FetchGroup.ALL.name()); - } - - @Override - public List getUserRoles(final UserPrincipal user) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class) - .getUserRoles(user.getClass(), user.getUsername())); - } - - public List getUnassignedProjects(final String username) { - return getUnassignedProjects(getUserPrincipal(username)); - } - - public List getUnassignedProjects(final UserPrincipal user) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).getUserUnassignedProjects( - user.getClass(), - user.getUsername())); - } - - public List getUnassignedRolePermissions(final Role role) { - final List permissions = new ArrayList<>(); - - final var permissionNames = role.getPermissions().stream() - .map(Permission::getName) - .toList(); - - final Query query = pm.newQuery(Permission.class) - .filter("!:permissionNames.contains(name)") - .setNamedParameters(Map.of("permissionNames", permissionNames)); - - permissions.addAll(executeAndCloseList(query)); - - return permissions; - } - - @Override - public Role updateRole(final Role transientRole) { - final Role role = getObjectByUuid(Role.class, transientRole.getUuid()); - if (role == null) - return null; - - role.setName(transientRole.getName()); - role.setDescription(transientRole.getDescription()); - - return persist(role); - } - - @Override - public List getUserProjectPermissions(final String username, final String projectName) { - final UserPrincipal user = getUserPrincipal(username); - final String columnName; - - switch (user) { - case LdapUser ldapUser -> columnName = "LDAPUSER_ID"; - case ManagedUser managedUser -> columnName = "MANAGEDUSER_ID"; - case OidcUser oidcUser -> columnName = "OIDCUSER_ID"; - default -> { - return null; - } - } - - final Query projectsQuery = pm.newQuery(Project.class) - .filter("name == :projectName") - .setNamedParameters(Map.of("projectName", projectName)); - - final String projectIds = executeAndCloseList(projectsQuery).stream() - .map(Project::getId) - .map(String::valueOf) - .collect(Collectors.joining(", ", "'{", "}'")); - - // language=SQL - final var queryString = """ - SELECT - upep."LDAPUSER_ID", - upep."MANAGEDUSER_ID", - upep."OIDCUSER_ID", - upep."PROJECT_ID", - upep."PERMISSION_ID", - upep."PERMISSION_NAME" - FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" upep - WHERE upep."%s" = :userId - AND upep."PROJECT_ID" = ANY(%s) - """.formatted(columnName, projectIds); - - final Query query = pm.newQuery(Query.SQL, queryString); - query.setNamedParameters(Map.of( - "userId", user.getId(), - "projectIds", projectIds)); - - return executeAndCloseResultList(query, UserProjectEffectivePermissionsRow.class) - .stream() - .map(UserProjectEffectivePermissionsRow::permissionName) - .map(this::getPermission) - .distinct() - .toList(); - } - - @Override - public boolean addRoleToUser(final UserPrincipal user, final Role role, final Project project) { - return JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser( - user.getClass(), - user.getId(), - project.getId(), - role.getId())) == 1; - } - - @Override - public boolean removeRoleFromUser(final UserPrincipal user, final Role role, final Project project) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser( - user.getClass(), - user.getId(), - project.getName(), - role.getId())) > 0; - } - -} diff --git a/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java deleted file mode 100644 index 7990b5ebea..0000000000 --- a/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.persistence.jdbi; - -import java.util.List; - -import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRole; -import org.dependencytrack.persistence.jdbi.mapping.ProjectRoleRowMapper; - -import org.jdbi.v3.sqlobject.config.RegisterFieldMapper; -import org.jdbi.v3.sqlobject.config.RegisterRowMapper; -import org.jdbi.v3.sqlobject.customizer.Bind; -import org.jdbi.v3.sqlobject.customizer.Define; -import org.jdbi.v3.sqlobject.customizer.DefineNamedBindings; -import org.jdbi.v3.sqlobject.statement.SqlQuery; -import org.jdbi.v3.sqlobject.statement.SqlUpdate; - -import alpine.model.UserPrincipal; - -/** - * @since 5.6.0 - */ -public interface RoleDao { - - @SqlUpdate(/* language=sql */ """ - DELETE - FROM "ROLE" - WHERE "ID" = :roleId - """) - int deleteRole(@Bind final long roleId); - - @SqlUpdate(/* language=sql */ """ - <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = userClass.getSimpleName()?upper_case> - INSERT INTO "${prefix}S_PROJECTS_ROLES" - ("${prefix}_ID", "PROJECT_ID", "ROLE_ID") - VALUES - (:userId, :projectId, :roleId) - ON CONFLICT DO NOTHING - """) - @DefineNamedBindings - int addRoleToUser( - @Define Class userClass, - @Bind long userId, - @Bind long projectId, - @Bind long roleId); - - @SqlUpdate(/* language=sql */ """ - <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = userClass.getSimpleName()?upper_case> - DELETE - FROM "${prefix}S_PROJECTS_ROLES" - WHERE "${prefix}_ID" = :userId - AND "ROLE_ID" = :roleId - AND "PROJECT_ID" IN ( - SELECT "ID" - FROM "PROJECT" - WHERE "NAME" = :projectName - ) - """) - @DefineNamedBindings - int removeRoleFromUser( - @Define Class userClass, - @Bind long userId, - @Bind String projectName, - @Bind long roleId); - - @SqlQuery(/* language=sql */ """ - <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = userClass.getSimpleName()?upper_case> - SELECT - p."ID" AS "PROJECT_ID", - p."NAME" AS "PROJECT_NAME", - p."UUID" AS "PROJECT_UUID", - r."ID" AS "ROLE_ID", - r."NAME" AS "ROLE_NAME", - r."UUID" AS "ROLE_UUID", - u."ID" AS "${prefix}_ID" - FROM "PROJECT" p - INNER JOIN "${prefix}S_PROJECTS_ROLES" pr - ON pr."PROJECT_ID" = p."ID" - INNER JOIN "${prefix}" u - ON u."ID" = pr."${prefix}_ID" - INNER JOIN "ROLE" r - ON r."ID" = pr."ROLE_ID" - WHERE u."USERNAME" = :username - """) - @RegisterRowMapper(ProjectRoleRowMapper.class) - @DefineNamedBindings - List getUserRoles(@Define Class userClass, @Bind String username); - - @SqlQuery(/* language=sql */ """ - <#-- @ftlvariable name="user" type="alpine.model.UserPrincipal" --> - <#assign prefix = userClass.getSimpleName()?upper_case> - SELECT p."ID", p."NAME", p."UUID" - FROM "PROJECT" p - LEFT JOIN "${prefix}S_PROJECTS_ROLES" pr - ON pr."PROJECT_ID" = p."ID" - LEFT JOIN "${prefix}" u - ON u."ID" = pr."${prefix}_ID" - WHERE u."USERNAME" != :username - OR u."USERNAME" IS NULL - """) - @RegisterFieldMapper(Project.class) - List getUserUnassignedProjects( - @Define Class userClass, - @Bind String username); - -} diff --git a/src/main/resources/migration/changelog-v5.6.0.xml b/src/main/resources/migration/changelog-v5.6.0.xml deleted file mode 100644 index 5d0ed6292d..0000000000 --- a/src/main/resources/migration/changelog-v5.6.0.xml +++ /dev/null @@ -1,918 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UPDATE "PROJECT" - SET "AUTHORS" = JSON_BUILD_ARRAY(JSON_BUILD_OBJECT('name', "AUTHOR"))::TEXT - WHERE "AUTHOR" IS NOT NULL; - - - UPDATE "COMPONENT" - SET "AUTHORS" = JSON_BUILD_ARRAY(JSON_BUILD_OBJECT('name', "AUTHOR"))::TEXT - WHERE "AUTHOR" IS NOT NULL; - - - - - - - - - - - - - - - - CREATE - INDEX "COMPONENT_DIRECT_DEPENDENCIES_JSONB_IDX" - ON "COMPONENT" - USING GIN("DIRECT_DEPENDENCIES" JSONB_PATH_OPS); - - - - - - DELETE FROM "CONFIGPROPERTY" - WHERE "GROUPNAME" = 'artifact' - AND "PROPERTYNAME" = 'bom.validation.enabled'; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DELETE - FROM "CONFIGPROPERTY" - WHERE "GROUPNAME" = 'vuln-source' - AND "PROPERTYNAME" = 'nvd.feeds.url'; - - - - - - CREATE INDEX "COMPONENT_PROPERTY_COMPONENT_ID_IDX" - ON "COMPONENT_PROPERTY" ("COMPONENT_ID"); - - - - - - - - - - - UPDATE "PROJECT" SET "INACTIVE_SINCE" = NOW() WHERE "ACTIVE" IS FALSE - - - - - - - - - - - - - - - - - - - - - - - - - - - - CREATE INDEX "COMPONENT_BLAKE2B_256_IDX" ON "COMPONENT" ("BLAKE2B_256") WHERE "BLAKE2B_256" IS NOT NULL; - CREATE INDEX "COMPONENT_BLAKE2B_384_IDX" ON "COMPONENT" ("BLAKE2B_384") WHERE "BLAKE2B_384" IS NOT NULL; - CREATE INDEX "COMPONENT_BLAKE2B_512_IDX" ON "COMPONENT" ("BLAKE2B_512") WHERE "BLAKE2B_512" IS NOT NULL; - CREATE INDEX "COMPONENT_BLAKE3_IDX" ON "COMPONENT" ("BLAKE3") WHERE "BLAKE3" IS NOT NULL; - CREATE INDEX "COMPONENT_MD5_IDX" ON "COMPONENT" ("MD5") WHERE "MD5" IS NOT NULL; - CREATE INDEX "COMPONENT_SHA1_IDX" ON "COMPONENT" ("SHA1") WHERE "SHA1" IS NOT NULL; - CREATE INDEX "COMPONENT_SHA_256_IDX" ON "COMPONENT" ("SHA_256") WHERE "SHA_256" IS NOT NULL; - CREATE INDEX "COMPONENT_SHA_384_IDX" ON "COMPONENT" ("SHA_384") WHERE "SHA_384" IS NOT NULL; - CREATE INDEX "COMPONENT_SHA_512_IDX" ON "COMPONENT" ("SHA_512") WHERE "SHA_512" IS NOT NULL; - CREATE INDEX "COMPONENT_SHA3_256_IDX" ON "COMPONENT" ("SHA3_256") WHERE "SHA3_256" IS NOT NULL; - CREATE INDEX "COMPONENT_SHA3_384_IDX" ON "COMPONENT" ("SHA3_384") WHERE "SHA3_384" IS NOT NULL; - CREATE INDEX "COMPONENT_SHA3_512_IDX" ON "COMPONENT" ("SHA3_512") WHERE "SHA3_512" IS NOT NULL; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WITH - cte_duplicate AS ( - SELECT "PROJECT_ID" - , "TEAM_ID" - FROM "PROJECT_ACCESS_TEAMS" - GROUP BY "PROJECT_ID" - , "TEAM_ID" - HAVING COUNT(*) > 1 - ), - cte_deleted_duplicate AS ( - DELETE FROM "PROJECT_ACCESS_TEAMS" - USING cte_duplicate - WHERE cte_duplicate."PROJECT_ID" = "PROJECT_ACCESS_TEAMS"."PROJECT_ID" - AND cte_duplicate."TEAM_ID" = "PROJECT_ACCESS_TEAMS"."TEAM_ID" - ) - INSERT INTO "PROJECT_ACCESS_TEAMS" ("PROJECT_ID", "TEAM_ID") - SELECT "PROJECT_ID", "TEAM_ID" FROM cte_duplicate - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SELECT - lpr."LDAPUSER_ID" AS "LDAPUSER_ID", - mpr."MANAGEDUSER_ID" AS "MANAGEDUSER_ID", - opr."OIDCUSER_ID" AS "OIDCUSER_ID", - pr."ID" AS "PROJECT_ID", - p."ID" AS "PERMISSION_ID", - p."NAME" AS "PERMISSION_NAME" - FROM "PERMISSION" p - INNER JOIN "ROLES_PERMISSIONS" rp - ON rp."PERMISSION_ID" = p."ID" - FULL OUTER JOIN "LDAPUSERS_PROJECTS_ROLES" lpr - ON lpr."ROLE_ID" = rp."ROLE_ID" - FULL OUTER JOIN "MANAGEDUSERS_PROJECTS_ROLES" mpr - ON lpr."PROJECT_ID" = mpr."PROJECT_ID" - AND lpr."ROLE_ID" = mpr."ROLE_ID" - FULL OUTER JOIN "OIDCUSERS_PROJECTS_ROLES" opr - ON mpr."PROJECT_ID" = opr."PROJECT_ID" - AND mpr."ROLE_ID" = opr."ROLE_ID" - INNER JOIN "PROJECT" pr - ON lpr."PROJECT_ID" = pr."ID" - OR mpr."PROJECT_ID" = pr."ID" - OR opr."PROJECT_ID" = pr."ID" - - - diff --git a/src/main/resources/migration/procedures/function_has-project-access.sql b/src/main/resources/migration/procedures/function_has-project-access.sql deleted file mode 100644 index 3fd727255b..0000000000 --- a/src/main/resources/migration/procedures/function_has-project-access.sql +++ /dev/null @@ -1,54 +0,0 @@ -create or replace function has_project_access( - project_id bigint, - team_ids bigint[], - role_ids bigint[] -) returns bool - language "sql" - parallel safe - stable -as -$$ -with recursive project_hierarchy(id, parent_id) as( - select "ID" as id, - "PARENT_PROJECT_ID" as parent_id - from "PROJECT" - where "ID" = project_id - union all - select "PROJECT"."ID" as id, - "PROJECT"."PARENT_PROJECT_ID" as parent_id - from "PROJECT" - inner join project_hierarchy - on project_hierarchy.parent_id = "PROJECT"."ID" -) -select coalesce( - ( - select true - from project_hierarchy - inner join "PROJECT_ACCESS_TEAMS" - on "PROJECT_ACCESS_TEAMS"."PROJECT_ID" = project_hierarchy.id - where "PROJECT_ACCESS_TEAMS"."TEAM_ID" = any(team_ids) - ), - ( - select true - from project_hierarchy - inner join "LDAPUSERS_PROJECTS_ROLES" - on "LDAPUSERS_PROJECTS_ROLES"."PROJECT_ID" = project_hierarchy.id - where "LDAPUSERS_PROJECTS_ROLES"."ROLE_ID" = any(role_ids) - ), - ( - select true - from project_hierarchy - inner join "MANAGEDUSERS_PROJECTS_ROLES" - on "MANAGEDUSERS_PROJECTS_ROLES"."PROJECT_ID" = project_hierarchy.id - where "MANAGEDUSERS_PROJECTS_ROLES"."ROLE_ID" = any(role_ids) - ), - ( - select true - from project_hierarchy - inner join "OIDCUSERS_PROJECTS_ROLES" - on "OIDCUSERS_PROJECTS_ROLES"."PROJECT_ID" = project_hierarchy.id - where "OIDCUSERS_PROJECTS_ROLES"."ROLE_ID" = any(role_ids) - ), - false -) -$$; \ No newline at end of file From 7e7d87ebba9a57dd3dfe80632a94279a032d9dcf Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Fri, 23 May 2025 16:23:29 -0600 Subject: [PATCH 26/45] tests: codacy cleanup Signed-off-by: Allen Shearin --- .../persistence/RoleQueryManagerTest.java | 21 +++++++++++++------ .../resources/v1/RoleResourceTest.java | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 9e1f24bea1..b0522f2989 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -27,6 +27,7 @@ import alpine.model.ManagedUser; import alpine.model.Permission; +import alpine.server.auth.PasswordService; import java.text.DateFormat; import java.text.ParseException; @@ -52,6 +53,7 @@ public class RoleQueryManagerTest extends PersistenceCapableTest { private PostgreSQLContainer postgresContainer; + private static final String TEST_ROLE_PASSWORD_HASH = new String(PasswordService.createHash("testuser".toCharArray())); @Before public void setUp() { @@ -154,7 +156,7 @@ public void testGetUserRoles() throws ParseException { testUser.setUsername("test-user"); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); qm.persist(testUser); final var expectedRole = new Role(); @@ -184,7 +186,7 @@ public void testGetUnassignedProjects() throws ParseException { testUser.setUsername(testUserName); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); qm.persist(testUser); final var maintainerRole = new Role(); @@ -264,7 +266,7 @@ public void testGetUnassignedRolePermissions() throws ParseException { testUser.setUsername("test-user"); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); testUser.setPermissions(expectedPermissionsList); qm.persist(testUser); @@ -321,7 +323,7 @@ public void testGetUserProjectPermissions() throws ParseException { testUser.setUsername("test-user"); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); testUser.setPermissions(expectedPermissionsList); qm.persist(testUser); @@ -371,7 +373,7 @@ public void testAddRoleToUser() throws ParseException { testUser.setUsername("test-user"); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); qm.persist(testUser); final var maintainerRole = new Role(); @@ -380,6 +382,13 @@ public void testAddRoleToUser() throws ParseException { qm.persist(maintainerRole); qm.addRoleToUser(testUser, maintainerRole, testProject); + + Assert.assertEquals( + qm.getRoles().size(), + 1); + Assert.assertEquals( + qm.getRoles().get(0).getName(), + maintainerRole.getName()); } @Test @@ -396,7 +405,7 @@ public void testRemoveRoleFromUser() throws ParseException { testUser.setUsername("test-user"); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); qm.persist(testUser); final var maintainerRole = new Role(); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java index e69d9bef78..5f49f57cf6 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -164,7 +164,7 @@ public void getUserRolesTest() throws ParseException { testUser.setUsername("test-user"); DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword("password"); + testUser.setPassword(TEST_USER_PASSWORD_HASH); qm.persist(testUser); final var expectedRole = new Role(); From 025e1927a5aac7466ca97def005db7184c64ea1a Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Sat, 24 May 2025 11:30:27 -0600 Subject: [PATCH 27/45] fix: remove getUserProjectPermissions from roleQueryManager Signed-off-by: Allen Shearin --- .../persistence/QueryManager.java | 4 -- .../persistence/RoleQueryManager.java | 62 ++-------------- .../persistence/RoleQueryManagerTest.java | 72 ------------------- 3 files changed, 5 insertions(+), 133 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 4b58deb11c..1ef25bbda2 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -1149,10 +1149,6 @@ public List getUserRoles(final User user) { return getRoleQueryManager().getUserRoles(user); } - public List getUserProjectPermissions(final String username, final String projectName) { - return getRoleQueryManager().getUserProjectPermissions(username, projectName); - } - public boolean removeRoleFromUser(final User user, final Role role, final Project project) { return getRoleQueryManager().removeRoleFromUser(user, role, project); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index fbc5c7a247..593b3845b0 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import javax.jdo.PersistenceManager; import javax.jdo.Query; @@ -36,9 +35,6 @@ import org.apache.commons.lang3.StringUtils; import alpine.common.logging.Logger; -import alpine.model.LdapUser; -import alpine.model.ManagedUser; -import alpine.model.OidcUser; import alpine.model.Permission; import alpine.model.User; import alpine.resources.AlpineRequest; @@ -51,12 +47,14 @@ final class RoleQueryManager extends QueryManager implements IQueryManager { * @since 5.6.0 */ public record UserProjectEffectivePermissionsRow( - Long ldapUserId, - Long managedUserId, - Long oidcUserId, + Long userId, Long projectId, Long permissionId, String permissionName) { + + public UserProjectEffectivePermissionsRow () { + this(null, null, null, null); + } } private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); @@ -147,56 +145,6 @@ public Role updateRole(final Role transientRole) { return persist(role); } - @Override - public List getUserProjectPermissions(final String username, final String projectName) { - final User user = getUser(username); - final String columnName; - - switch (user) { - case LdapUser ldapUser -> columnName = "LDAPUSER_ID"; - case ManagedUser managedUser -> columnName = "MANAGEDUSER_ID"; - case OidcUser oidcUser -> columnName = "OIDCUSER_ID"; - default -> { - return null; - } - } - - final Query projectsQuery = pm.newQuery(Project.class) - .filter("name == :projectName") - .setNamedParameters(Map.of("projectName", projectName)); - - final String projectIds = executeAndCloseList(projectsQuery).stream() - .map(Project::getId) - .map(String::valueOf) - .collect(Collectors.joining(", ", "(", ")")); - - // language=SQL - final var queryString = """ - SELECT - upep."LDAPUSER_ID", - upep."MANAGEDUSER_ID", - upep."OIDCUSER_ID", - upep."PROJECT_ID", - upep."PERMISSION_ID", - upep."PERMISSION_NAME" - FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" upep - WHERE upep."%s" = :userId - AND upep."PROJECT_ID" IN %s - """.formatted(columnName, projectIds); - - final Query query = pm.newQuery(Query.SQL, queryString); - query.setNamedParameters(Map.of( - "userId", user.getId(), - "projectIds", projectIds)); - - return executeAndCloseResultList(query, UserProjectEffectivePermissionsRow.class) - .stream() - .map(UserProjectEffectivePermissionsRow::permissionName) - .map(this::getPermission) - .distinct() - .toList(); - } - @Override public boolean addRoleToUser(final User user, final Role role, final Project project) { return JdbiFactory.withJdbiHandle( diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index b0522f2989..3bcd3fe711 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -34,8 +34,6 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -287,76 +285,6 @@ public void testUpdateRole() { Role actualRole = qm.updateRole(maintainerRole); Assert.assertEquals(maintainerRole, actualRole); - - // TODO: Check requirements of `updateRole`. - } - - @Test - public void testGetUserProjectPermissions() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var readPermission = new Permission(); - readPermission.setId(1); - readPermission.setName("read"); - readPermission.setDescription("permission to read"); - qm.persist(readPermission); - - final var writePermission = new Permission(); - writePermission.setId(2); - writePermission.setName("write"); - writePermission.setDescription("permission to write"); - qm.persist(writePermission); - - List expectedPermissionsList = Arrays.asList( - readPermission, - writePermission); - - Set expectedPermissions = new HashSet<>(expectedPermissionsList); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - testUser.setPermissions(expectedPermissionsList); - qm.persist(testUser); - - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - maintainerRole.setPermissions(expectedPermissions); - qm.persist(maintainerRole); - - JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addPermissionToRole( - maintainerRole.getId(), - readPermission.getId())); - - JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addPermissionToRole( - maintainerRole.getId(), - writePermission.getId())); - - JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getId(), - testProject.getId(), - maintainerRole.getId())); - - List actualPermissions = qm.getUserProjectPermissions("test-user", "test-project"); - List actualPermissionsSorted = new ArrayList(); - for (Permission p : actualPermissions) { - actualPermissionsSorted.add(p); - } - Collections.sort(actualPermissionsSorted, Comparator.comparing(Permission::getId)); - - Assert.assertEquals(expectedPermissionsList, actualPermissionsSorted); } @Test From 6fee046e48df3dfb13ecfc3d53e2671209829d07 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Sat, 24 May 2025 14:15:47 -0600 Subject: [PATCH 28/45] fix: adjust asserts in testGetUnassignedProjects Signed-off-by: Allen Shearin --- .../dependencytrack/persistence/RoleQueryManager.java | 4 ---- .../persistence/RoleQueryManagerTest.java | 10 ++++++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 593b3845b0..a51e22aa92 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -51,10 +51,6 @@ public record UserProjectEffectivePermissionsRow( Long projectId, Long permissionId, String permissionName) { - - public UserProjectEffectivePermissionsRow () { - this(null, null, null, null); - } } private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 3bcd3fe711..8394d34762 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -200,7 +200,6 @@ public void testGetUnassignedProjects() throws ParseException { final var assignedProject = new Project(); assignedProject.setId(2); assignedProject.setName("test-project-2"); - qm.persist(assignedProject); final var unassignedProject2 = new Project(); @@ -220,7 +219,14 @@ public void testGetUnassignedProjects() throws ParseException { List actualProjects = qm.getUnassignedProjects(testUserName); - Assert.assertEquals(expectedProjects.toString(), actualProjects.toString()); + // Sort both lists by project name before asserting equivalence + expectedProjects.sort((p1, p2) -> p1.getName().compareTo(p2.getName())); + actualProjects.sort((p1, p2) -> p1.getName().compareTo(p2.getName())); + + Assert.assertEquals(expectedProjects.size(), actualProjects.size()); + for (int i = 0; i < expectedProjects.size(); i++) { + Assert.assertEquals(expectedProjects.get(i).getName(), actualProjects.get(i).getName()); + } } @Test From ba51997f54ba8b44a415224aff48c6d098c3c4ed Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Mon, 26 May 2025 15:16:06 -0600 Subject: [PATCH 29/45] refactor: address PR comments - Renamed ProjectRole to ProjectRoleBinding - Remove order annotation from Role Permissions - Reset ProjectQueryManager:hasAccess - Remove unused UserProjectEffectivePermissionsRow from RoleQueryManager - Updated deleteRole API to take UUID in path - Renamed getUesrRoles API endpoint to be singular - Removed unneeded setup in RoleQueryManagerTest - Updated UserResourceAuthenticatedTest to use updated endpoints - Updated persistence/jooq files with namechanges Signed-off-by: Allen Shearin --- ...ojectRole.java => ProjectRoleBinding.java} | 6 +- .../java/org/dependencytrack/model/Role.java | 3 - .../persistence/ProjectQueryManager.java | 28 ++-- .../persistence/QueryManager.java | 12 +- .../persistence/RoleQueryManager.java | 21 +-- .../persistence/jdbi/RoleDao.java | 20 +-- ....java => ProjectRoleRowBindingMapper.java} | 8 +- .../resources/v1/AccessControlResource.java | 2 +- .../resources/v1/RoleResource.java | 25 ++-- .../resources/v1/UserResource.java | 6 +- .../main/resources/META-INF/persistence.xml | 2 +- .../persistence/RoleQueryManagerTest.java | 31 +---- .../v1/UserResourceAuthenticatedTest.java | 8 +- .../jooq/generated/DefaultSchema.java | 8 +- .../persistence/jooq/generated/Indexes.java | 6 +- .../persistence/jooq/generated/Keys.java | 10 +- .../persistence/jooq/generated/Tables.java | 6 +- .../jooq/generated/tables/Project.java | 6 +- ...ectsRoles.java => ProjectRoleBinding.java} | 114 ++++++++-------- .../jooq/generated/tables/Role.java | 6 +- .../jooq/generated/tables/User.java | 6 +- ...ord.java => ProjectRoleBindingRecord.java} | 30 ++--- .../resources/migration/changelog-v5.6.0.xml | 127 +++++++++++++----- 23 files changed, 257 insertions(+), 234 deletions(-) rename apiserver/src/main/java/org/dependencytrack/model/{ProjectRole.java => ProjectRoleBinding.java} (94%) rename apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/{ProjectRoleRowMapper.java => ProjectRoleRowBindingMapper.java} (88%) rename persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/{UsersProjectsRoles.java => ProjectRoleBinding.java} (60%) rename persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/{UsersProjectsRolesRecord.java => ProjectRoleBindingRecord.java} (61%) diff --git a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/ProjectRoleBinding.java similarity index 94% rename from apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java rename to apiserver/src/main/java/org/dependencytrack/model/ProjectRoleBinding.java index 05dfccdd99..380b0c0369 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/ProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/ProjectRoleBinding.java @@ -44,15 +44,15 @@ * @author Jonathan Howard * @since 5.6.0 */ -@PersistenceCapable(table = "USERS_PROJECTS_ROLES") +@PersistenceCapable(table = "PROJECT_ROLE_BINDING") @JsonInclude(JsonInclude.Include.NON_NULL) -@Unique(name = "USERS_PROJECTS_ROLES_COMPOSITE_IDX", members = { "users", "project", "role" }) +@Unique(name = "PROJECT_ROLE_BINDING_COMPOSITE_IDX", members = { "users", "project", "role" }) @FetchGroup(name = "ALL", members = { @Persistent(name = "role"), @Persistent(name = "project"), @Persistent(name = "users") }) -public class ProjectRole implements Serializable { +public class ProjectRoleBinding implements Serializable { @Persistent(defaultFetchGroup = "true") @Column(name = "ROLE_ID", allowsNull = "false") diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 15ea00f4ef..2d282f0923 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -40,11 +40,9 @@ import javax.jdo.annotations.Column; import javax.jdo.annotations.Element; -import javax.jdo.annotations.Extension; import javax.jdo.annotations.FetchGroup; import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.Join; -import javax.jdo.annotations.Order; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; @@ -93,7 +91,6 @@ public enum FetchGroup { @Unique(name = "ROLES_PERMISSIONS_IDX") @Join(column = "ROLE_ID") @Element(column = "PERMISSION_ID") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "name ASC")) private Set permissions = new LinkedHashSet<>(); @Persistent(customValueStrategy = "uuid") diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java index 36605d37ff..5028f2db6d 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java @@ -1021,23 +1021,31 @@ public void bind(final Project project, final Collection tags) { @Override public boolean hasAccess(final Principal principal, final Project project) { - if (!isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED) - || principal == null // System request (e.g. MetricsUpdateTask, etc) where there isn't a principal - || super.hasAccessManagementPermission(principal)) // TODO: After Alpine >= 3.2.0: request.getEffectivePermission().contains(Permissions.ACCESS_MANAGEMENT.name()) + if (principal == null) { + // This is a system request being made (e.g. MetricsUpdateTask, etc) where there isn't a principal return true; + } - final Set roleIds = getRoleIds(principal, project); - final Set teamIds = getTeamIds(principal); + if (!isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED)) { + return true; + } - if (teamIds.isEmpty() && roleIds.isEmpty()) + // TODO: After upgrading to Alpine >= 3.2.0, this should become: + // request.getEffectivePermission().contains(Permissions.ACCESS_MANAGEMENT.name()) + // https://github.com/stevespringett/Alpine/pull/764 + if (super.hasAccessManagementPermission(principal)) { + return true; + } + + final Set teamIds = getTeamIds(principal); + if (teamIds.isEmpty()) { return false; + } - final Query query = pm.newQuery(Query.SQL, "SELECT HAS_PROJECT_ACCESS(:projectId, :teamIds, :roleIds)"); + final Query query = pm.newQuery(Query.SQL, "SELECT HAS_PROJECT_ACCESS(:projectId, :teamIds)"); query.setNamedParameters(Map.ofEntries( Map.entry("projectId", project.getId()), - Map.entry("teamIds", teamIds.toArray(Long[]::new)), - Map.entry("roleIds", roleIds.toArray(Long[]::new)))); - + Map.entry("teamIds", teamIds.toArray(new Long[0])))); return executeAndCloseResultUnique(query, Boolean.class); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 1ef25bbda2..fadb3b01e2 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -67,7 +67,7 @@ import org.dependencytrack.model.PolicyViolation; import org.dependencytrack.model.Project; import org.dependencytrack.model.ProjectProperty; -import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.ProjectRoleBinding; import org.dependencytrack.model.Repository; import org.dependencytrack.model.RepositoryMetaComponent; import org.dependencytrack.model.RepositoryType; @@ -488,19 +488,19 @@ public QueryManager withL2CacheDisabled() { } /** - * Get the IDs of the {@link ProjectRole}s a given {@link Principal} is a member of. + * Get the IDs of the {@link ProjectRoleBinding}s a given {@link Principal} is a member of. * - * @return A {@link Set} of {@link ProjectRole} IDs + * @return A {@link Set} of {@link ProjectRoleBinding} IDs */ protected Set getRoleIds(final Principal principal, final Project project) { - final Query query = pm.newQuery(ProjectRole.class) + final Query query = pm.newQuery(ProjectRoleBinding.class) .filter("project.id == :projectId && users.contains(:principal)") .setNamedParameters(Map.ofEntries( Map.entry("principal", principal), Map.entry("projectId", project.getId()))); return Set.of(executeAndCloseList(query).stream() - .map(ProjectRole::getRole) + .map(ProjectRoleBinding::getRole) .map(Role::getId) .toArray(Long[]::new)); } @@ -1145,7 +1145,7 @@ public List getUnassignedRolePermissions(final Role role) { return getRoleQueryManager().getUnassignedRolePermissions(role); } - public List getUserRoles(final User user) { + public List getUserRoles(final User user) { return getRoleQueryManager().getUserRoles(user); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index a51e22aa92..b15ee5fb69 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -28,7 +28,7 @@ import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; -import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.ProjectRoleBinding; import org.dependencytrack.persistence.jdbi.JdbiFactory; import org.dependencytrack.persistence.jdbi.RoleDao; @@ -41,18 +41,6 @@ final class RoleQueryManager extends QueryManager implements IQueryManager { - /** - * Represents a row returned by the USER_PROJECT_EFFECTIVE_PERMISSIONS view. - * - * @since 5.6.0 - */ - public record UserProjectEffectivePermissionsRow( - Long userId, - Long projectId, - Long permissionId, - String permissionName) { - } - private static final Logger LOGGER = Logger.getLogger(RoleQueryManager.class); RoleQueryManager(final PersistenceManager pm) { @@ -70,6 +58,9 @@ public Role createRole(final String name, final List permissions) { role.setName(name); role.setPermissions(Set.copyOf(permissions)); + LOGGER.debug(name + " role created with permissions: " + + String.join(", ", permissions.stream().map(Permission::getName).toList())); + return persist(role); }); } @@ -80,6 +71,8 @@ public List getRoles() { if (orderBy == null) query.setOrdering("name asc"); + decorate(query); + return query.executeList(); } @@ -100,7 +93,7 @@ public Role getRole(final String uuid) { } @Override - public List getUserRoles(final User user) { + public List getUserRoles(final User user) { return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class) .getUserRoles(user.getUsername())); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java index 8a5e353a27..19d87c5b3b 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java @@ -21,8 +21,8 @@ import java.util.List; import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRole; -import org.dependencytrack.persistence.jdbi.mapping.ProjectRoleRowMapper; +import org.dependencytrack.model.ProjectRoleBinding; +import org.dependencytrack.persistence.jdbi.mapping.ProjectRoleRowBindingMapper; import org.jdbi.v3.sqlobject.config.RegisterFieldMapper; import org.jdbi.v3.sqlobject.config.RegisterRowMapper; @@ -52,7 +52,7 @@ public interface RoleDao { int addPermissionToRole(@Bind long roleId, @Bind long permissionId); @SqlUpdate(/* language=sql */ """ - INSERT INTO "USERS_PROJECTS_ROLES" + INSERT INTO "PROJECT_ROLE_BINDING" ("USER_ID", "PROJECT_ID", "ROLE_ID") VALUES (:userId, :projectId, :roleId) @@ -63,7 +63,7 @@ ON CONFLICT ("USER_ID", "PROJECT_ID") DO @SqlUpdate(/* language=sql */ """ DELETE - FROM "USERS_PROJECTS_ROLES" + FROM "PROJECT_ROLE_BINDING" WHERE "USER_ID" = :userId AND "ROLE_ID" = :roleId AND "PROJECT_ID" IN ( @@ -86,7 +86,7 @@ ON CONFLICT ("USER_ID", "PROJECT_ID") DO u."USERNAME" AS "USER_NAME", u."TYPE" AS "USER_TYPE" FROM "PROJECT" p - INNER JOIN "USERS_PROJECTS_ROLES" pr + INNER JOIN "PROJECT_ROLE_BINDING" pr ON pr."PROJECT_ID" = p."ID" INNER JOIN "USER" u ON u."ID" = pr."USER_ID" @@ -94,24 +94,24 @@ ON CONFLICT ("USER_ID", "PROJECT_ID") DO ON r."ID" = pr."ROLE_ID" WHERE u."USERNAME" = :username """) - @RegisterRowMapper(ProjectRoleRowMapper.class) - List getUserRoles(@Bind String username); + @RegisterRowMapper(ProjectRoleRowBindingMapper.class) + List getUserRoles(@Bind String username); @SqlQuery(/* language=sql */ """ SELECT EXISTS ( SELECT 1 - FROM "USERS_PROJECTS_ROLES" + FROM "PROJECT_ROLE_BINDING" WHERE "ROLE_ID" = :roleId AND "PROJECT_ID" = :projectId AND "USER_ID" = :userId ) """) - boolean userProjectRoleExists(@Bind long userId, @Bind long projectId, @Bind long roleId); + boolean userProjectRoleBindingExists(@Bind long userId, @Bind long projectId, @Bind long roleId); @SqlQuery(/* language=sql */ """ SELECT p."ID", p."NAME", p."UUID" FROM "PROJECT" p - LEFT JOIN "USERS_PROJECTS_ROLES" pr + LEFT JOIN "PROJECT_ROLE_BINDING" pr ON pr."PROJECT_ID" = p."ID" LEFT JOIN "USER" u ON u."ID" = pr."USER_ID" diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowBindingMapper.java similarity index 88% rename from apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java rename to apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowBindingMapper.java index d6bc2047c9..faeade58d5 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowMapper.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowBindingMapper.java @@ -24,7 +24,7 @@ import alpine.model.User; import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.ProjectRoleBinding; import org.dependencytrack.model.Role; import org.jdbi.v3.core.mapper.RowMapper; @@ -36,10 +36,10 @@ import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.maybeSet; -public class ProjectRoleRowMapper implements RowMapper { +public class ProjectRoleRowBindingMapper implements RowMapper { - public ProjectRole map(final ResultSet resultSet, final StatementContext ctx) throws SQLException { - final ProjectRole projectRole = new ProjectRole(); + public ProjectRoleBinding map(final ResultSet resultSet, final StatementContext ctx) throws SQLException { + final ProjectRoleBinding projectRole = new ProjectRoleBinding(); projectRole.setProject(new Project()); projectRole.setRole(new Role()); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index a9cda5498b..41fc390d0e 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -142,7 +142,7 @@ public Response retrieveUserProjects( if (user == null) return Response.status(Response.Status.NOT_FOUND).build(); - try (final Handle jdbiHandle = openJdbiHandle()) { + try (final Handle jdbiHandle = openJdbiHandle(getAlpineRequest())) { var dao = jdbiHandle.attach(RoleDao.class); List projects = dao.getUserUnassignedProjects(user.getUsername()); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index a639cbf4fc..2b1c107d6f 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -48,19 +48,15 @@ import org.dependencytrack.auth.Permissions; import org.dependencytrack.model.validation.ValidUuid; import org.dependencytrack.model.Role; -import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.ProjectRoleBinding; import org.dependencytrack.persistence.QueryManager; -import org.dependencytrack.persistence.jdbi.RoleDao; import org.dependencytrack.resources.v1.vo.CreateRoleRequest; -import org.jdbi.v3.core.Handle; import org.owasp.security.logging.SecurityMarkers; import alpine.model.Permission; import alpine.model.User; -import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; - import java.util.List; import java.util.Map; @@ -210,6 +206,7 @@ public Response updateRole(Role jsonRole) { } @DELETE + @Path("/{uuid}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( @@ -221,15 +218,17 @@ public Response updateRole(Role jsonRole) { @ApiResponse(responseCode = "404", description = "The role could not be found") }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE }) - public Response deleteRole(Role jsonRole) { + public Response deleteRole( + @Parameter( + description = "The UUID of the role to retrieve", + schema = @Schema(type = "string", format = "uuid"), + required = true) @PathParam("uuid") @ValidUuid String uuid) { try (QueryManager qm = new QueryManager()) { - final Role role = qm.getObjectByUuid(Role.class, jsonRole.getUuid(), Role.FetchGroup.ALL.name()); + final Role role = qm.getObjectByUuid(Role.class, uuid, Role.FetchGroup.ALL.name()); if (role == null) return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); - try (final Handle jdbiHandle = openJdbiHandle()) { - jdbiHandle.attach(RoleDao.class).deleteRole(role.getId()); - } + qm.delete(role); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Role deleted: " + role.getName()); @@ -238,7 +237,7 @@ public Response deleteRole(Role jsonRole) { } @GET - @Path("/{username}/roles") + @Path("/{username}/role") @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of roles assigned to the specified user", @@ -247,7 +246,7 @@ public Response deleteRole(Role jsonRole) { @ApiResponse( responseCode = "200", description = "A list of roles assigned to the user", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProjectRole.class)))), + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProjectRoleBinding.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) @@ -261,7 +260,7 @@ public Response getUserRoles( return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); } - List roles = qm.getUserRoles(user); + List roles = qm.getUserRoles(user); if (roles == null || roles.isEmpty()) { LOGGER.info("No roles found for user: " + username); return Response.ok(List.of()).build(); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 8e489d59b9..6d3df4681c 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -878,7 +878,7 @@ private UserSubject buildUserSubject(final String username, final String email) ) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) - public Response assignProjectRoleToUser( + public Response assignProjectRoleBindingToUser( @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); @@ -901,7 +901,7 @@ public Response assignProjectRoleToUser( } boolean exists = JdbiFactory.withJdbiHandle(getAlpineRequest(), handle -> handle.attach(RoleDao.class) - .userProjectRoleExists(user.getId(), project.getId(), role.getId())); + .userProjectRoleBindingExists(user.getId(), project.getId(), role.getId())); if (exists) return Response.notModified().build(); qm.addRoleToUser(user, role, project); @@ -937,7 +937,7 @@ public Response assignProjectRoleToUser( ) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) - public Response removeProjectRoleFromUser( + public Response removeProjectRoleBindingFromUser( @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); diff --git a/apiserver/src/main/resources/META-INF/persistence.xml b/apiserver/src/main/resources/META-INF/persistence.xml index ceebdf4bd6..261c4d1fb6 100644 --- a/apiserver/src/main/resources/META-INF/persistence.xml +++ b/apiserver/src/main/resources/META-INF/persistence.xml @@ -54,7 +54,7 @@ org.dependencytrack.model.Project org.dependencytrack.model.ProjectMetadata org.dependencytrack.model.ProjectProperty - org.dependencytrack.model.ProjectRole + org.dependencytrack.model.ProjectRoleBinding org.dependencytrack.model.Repository org.dependencytrack.model.RepositoryMetaComponent org.dependencytrack.model.Role diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 8394d34762..5ebbfed820 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -19,11 +19,10 @@ package org.dependencytrack.persistence; import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRole; +import org.dependencytrack.model.ProjectRoleBinding; import org.dependencytrack.model.Role; import org.dependencytrack.persistence.jdbi.JdbiFactory; import org.dependencytrack.persistence.jdbi.RoleDao; -import org.jdbi.v3.core.Jdbi; import alpine.model.ManagedUser; import alpine.model.Permission; @@ -39,41 +38,15 @@ import java.util.Set; import org.dependencytrack.PersistenceCapableTest; -import org.junit.After; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.utility.DockerImageName; import static org.assertj.core.api.Assertions.assertThat; public class RoleQueryManagerTest extends PersistenceCapableTest { - private PostgreSQLContainer postgresContainer; private static final String TEST_ROLE_PASSWORD_HASH = new String(PasswordService.createHash("testuser".toCharArray())); - @Before - public void setUp() { - System.setProperty("javax.jdo.PersistenceManagerFactoryClass", - "org.datanucleus.api.jdo.JDOPersistenceManagerFactory"); - - postgresContainer = new PostgreSQLContainer<>(DockerImageName.parse("postgres:11-alpine")); - postgresContainer.start(); - - Jdbi.create( - postgresContainer.getJdbcUrl(), - postgresContainer.getUsername(), - postgresContainer.getPassword()); - } - - @After - public void tearDown() { - if (postgresContainer != null) { - postgresContainer.stop(); - } - } - @Test public void testCreateRole() { final var readPermission = new Permission(); @@ -168,7 +141,7 @@ public void testGetUserRoles() throws ParseException { testProject.getId(), expectedRole.getId())); - List actualRoles = qm.getUserRoles(testUser); + List actualRoles = qm.getUserRoles(testUser); Assert.assertEquals(actualRoles.size(), 1); Assert.assertEquals(expectedRole.toString(), actualRoles.get(0).getRole().toString()); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java index afadc885a6..8c6fce7a92 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java @@ -754,7 +754,7 @@ public void setUserTeamsInvalidTest() { } @Test - public void assignProjectRoleToUserTest() { + public void assignProjectRoleBindingToUserTest() { // Arrange ManagedUser user = qm.createManagedUser("roleuser", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( @@ -783,7 +783,7 @@ public void assignProjectRoleToUserTest() { } @Test - public void assignProjectRoleToUserAlreadyAssignedTest() { + public void assignProjectRoleBindingToUserAlreadyAssignedTest() { ManagedUser user = qm.createManagedUser("roleuser2", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( "Test Project 2","null", @@ -807,7 +807,7 @@ public void assignProjectRoleToUserAlreadyAssignedTest() { } @Test - public void removeProjectRoleFromUserTest() { + public void removeProjectRoleBindingFromUserTest() { ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( "Test Project 3","null", @@ -831,7 +831,7 @@ public void removeProjectRoleFromUserTest() { } @Test - public void removeProjectRoleFromUserNotAssignedTest() { + public void removeProjectRoleBindingFromUserNotAssignedTest() { ManagedUser user = qm.createManagedUser("roleuser4", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( "Test Project 4","null", diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java index dcd69db81e..e77b7cb481 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java @@ -62,7 +62,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -370,9 +370,9 @@ public class DefaultSchema extends SchemaImpl { public final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; /** - * The table USERS_PROJECTS_ROLES. + * The table PROJECT_ROLE_BINDING. */ - public final UsersProjectsRoles USERS_PROJECTS_ROLES = UsersProjectsRoles.USERS_PROJECTS_ROLES; + public final ProjectRoleBinding PROJECT_ROLE_BINDING = ProjectRoleBinding.PROJECT_ROLE_BINDING; /** * The table USERS_TEAMS. @@ -513,7 +513,7 @@ public final List> getTables() { User.USER, UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, UsersPermissions.USERS_PERMISSIONS, - UsersProjectsRoles.USERS_PROJECTS_ROLES, + ProjectRoleBinding.PROJECT_ROLE_BINDING, UsersTeams.USERS_TEAMS, Vex.VEX, ViolationAnalysis.VIOLATIONANALYSIS, diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java index 6182ea8d3a..f619370fe5 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java @@ -39,7 +39,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponentsVulnerabilities; import org.dependencytrack.persistence.jooq.generated.tables.Tag; import org.dependencytrack.persistence.jooq.generated.tables.User; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysisComment; @@ -158,8 +158,8 @@ public class Indexes { public static final Index SERVICECOMPONENTS_VULNERABILITIES_VULNERABILITY_ID_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENTS_VULNERABILITIES_VULNERABILITY_ID_IDX"), ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES, new OrderField[] { ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES.vulnerabilityId }, false); public static final Index TAG_NAME_IDX = Internal.createIndex(DSL.name("TAG_NAME_IDX"), Tag.TAG, new OrderField[] { Tag.TAG.name }, true); public static final Index USER_USERNAME_IDX = Internal.createIndex(DSL.name("USER_USERNAME_IDX"), User.USER, new OrderField[] { User.USER.username }, true); - public static final Index USERS_PROJECTS_ROLES_ROLE_ID_IDX = Internal.createIndex(DSL.name("USERS_PROJECTS_ROLES_ROLE_ID_IDX"), UsersProjectsRoles.USERS_PROJECTS_ROLES, new OrderField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.roleId }, false); - public static final Index USERS_PROJECTS_ROLES_USER_PROJECT_IDX = Internal.createIndex(DSL.name("USERS_PROJECTS_ROLES_USER_PROJECT_IDX"), UsersProjectsRoles.USERS_PROJECTS_ROLES, new OrderField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.userId, UsersProjectsRoles.USERS_PROJECTS_ROLES.projectId }, true); + public static final Index PROJECT_ROLE_BINDING_ROLE_ID_IDX = Internal.createIndex(DSL.name("PROJECT_ROLE_BINDING_ROLE_ID_IDX"), ProjectRoleBinding.PROJECT_ROLE_BINDING, new OrderField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.roleId }, false); + public static final Index PROJECT_ROLE_BINDING_USER_PROJECT_IDX = Internal.createIndex(DSL.name("PROJECT_ROLE_BINDING_USER_PROJECT_IDX"), ProjectRoleBinding.PROJECT_ROLE_BINDING, new OrderField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.userId, ProjectRoleBinding.PROJECT_ROLE_BINDING.projectId }, true); public static final Index VEX_PROJECT_ID_IDX = Internal.createIndex(DSL.name("VEX_PROJECT_ID_IDX"), Vex.VEX, new OrderField[] { Vex.VEX.projectId }, false); public static final Index VIOLATIONANALYSIS_COMPONENT_ID_IDX = Internal.createIndex(DSL.name("VIOLATIONANALYSIS_COMPONENT_ID_IDX"), ViolationAnalysis.VIOLATIONANALYSIS, new OrderField[] { ViolationAnalysis.VIOLATIONANALYSIS.componentId }, false); public static final Index VIOLATIONANALYSIS_POLICYVIOLATION_ID_IDX = Internal.createIndex(DSL.name("VIOLATIONANALYSIS_POLICYVIOLATION_ID_IDX"), ViolationAnalysis.VIOLATIONANALYSIS, new OrderField[] { ViolationAnalysis.VIOLATIONANALYSIS.policyViolationId }, false); diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java index 6b98a520d2..e3ee7ee646 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java @@ -59,7 +59,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -127,7 +127,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.records.UserProjectEffectivePermissionsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UserRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UsersPermissionsRecord; -import org.dependencytrack.persistence.jooq.generated.tables.records.UsersProjectsRolesRecord; +import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectRoleBindingRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UsersTeamsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.VexRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.ViolationAnalysisCommentRecord; @@ -338,9 +338,9 @@ public class Keys { public static final ForeignKey USER_PROJECT_EFFECTIVE_PERMISSIONS_USER_FK = Internal.createForeignKey(UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, DSL.name("USER_PROJECT_EFFECTIVE_PERMISSIONS_USER_FK"), new TableField[] { UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_PERMISSIONS_PERMISSION_FK = Internal.createForeignKey(UsersPermissions.USERS_PERMISSIONS, DSL.name("USERS_PERMISSIONS_PERMISSION_FK"), new TableField[] { UsersPermissions.USERS_PERMISSIONS.permissionId }, Keys.PERMISSION_PK, new TableField[] { Permission.PERMISSION.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_PERMISSIONS_USER_FK = Internal.createForeignKey(UsersPermissions.USERS_PERMISSIONS, DSL.name("USERS_PERMISSIONS_USER_FK"), new TableField[] { UsersPermissions.USERS_PERMISSIONS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); - public static final ForeignKey USERS_PROJECTS_ROLES_PROJECT_FK = Internal.createForeignKey(UsersProjectsRoles.USERS_PROJECTS_ROLES, DSL.name("USERS_PROJECTS_ROLES_PROJECT_FK"), new TableField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); - public static final ForeignKey USERS_PROJECTS_ROLES_ROLE_FK = Internal.createForeignKey(UsersProjectsRoles.USERS_PROJECTS_ROLES, DSL.name("USERS_PROJECTS_ROLES_ROLE_FK"), new TableField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.roleId }, Keys.ROLE_PK, new TableField[] { Role.ROLE.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); - public static final ForeignKey USERS_PROJECTS_ROLES_USER_FK = Internal.createForeignKey(UsersProjectsRoles.USERS_PROJECTS_ROLES, DSL.name("USERS_PROJECTS_ROLES_USER_FK"), new TableField[] { UsersProjectsRoles.USERS_PROJECTS_ROLES.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey PROJECT_ROLE_BINDING_PROJECT_FK = Internal.createForeignKey(ProjectRoleBinding.PROJECT_ROLE_BINDING, DSL.name("PROJECT_ROLE_BINDING_PROJECT_FK"), new TableField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey PROJECT_ROLE_BINDING_ROLE_FK = Internal.createForeignKey(ProjectRoleBinding.PROJECT_ROLE_BINDING, DSL.name("PROJECT_ROLE_BINDING_ROLE_FK"), new TableField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.roleId }, Keys.ROLE_PK, new TableField[] { Role.ROLE.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey PROJECT_ROLE_BINDING_USER_FK = Internal.createForeignKey(ProjectRoleBinding.PROJECT_ROLE_BINDING, DSL.name("PROJECT_ROLE_BINDING_USER_FK"), new TableField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_TEAMS_TEAM_FK = Internal.createForeignKey(UsersTeams.USERS_TEAMS, DSL.name("USERS_TEAMS_TEAM_FK"), new TableField[] { UsersTeams.USERS_TEAMS.teamId }, Keys.TEAM_PK, new TableField[] { Team.TEAM.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_TEAMS_USER_FK = Internal.createForeignKey(UsersTeams.USERS_TEAMS, DSL.name("USERS_TEAMS_USER_FK"), new TableField[] { UsersTeams.USERS_TEAMS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey VEX_PROJECT_FK = Internal.createForeignKey(Vex.VEX, DSL.name("VEX_PROJECT_FK"), new TableField[] { Vex.VEX.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java index e92954215b..6099c07b8d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java @@ -59,7 +59,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -356,9 +356,9 @@ public class Tables { public static final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; /** - * The table USERS_PROJECTS_ROLES. + * The table PROJECT_ROLE_BINDING. */ - public static final UsersProjectsRoles USERS_PROJECTS_ROLES = UsersProjectsRoles.USERS_PROJECTS_ROLES; + public static final ProjectRoleBinding PROJECT_ROLE_BINDING = ProjectRoleBinding.PROJECT_ROLE_BINDING; /** * The table USERS_TEAMS. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java index 244fa8918a..4c8546b71a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java @@ -34,7 +34,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.Tag.TagPath; import org.dependencytrack.persistence.jooq.generated.tables.Team.TeamPath; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions.UserProjectEffectivePermissionsPath; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles.UsersProjectsRolesPath; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding.UsersProjectsRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.Vex.VexPath; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis.ViolationAnalysisPath; import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectRecord; @@ -538,11 +538,11 @@ public UserProjectEffectivePermissionsPath userProjectEffectivePermissions() { /** * Get the implicit to-many join path to the - * USERS_PROJECTS_ROLES table + * PROJECT_ROLE_BINDING table */ public UsersProjectsRolesPath usersProjectsRoles() { if (_usersProjectsRoles == null) - _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.USERS_PROJECTS_ROLES_PROJECT_FK.getInverseKey()); + _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.PROJECT_ROLE_BINDING_PROJECT_FK.getInverseKey()); return _usersProjectsRoles; } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersProjectsRoles.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectRoleBinding.java similarity index 60% rename from persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersProjectsRoles.java rename to persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectRoleBinding.java index 174bb3074f..0d24f58833 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersProjectsRoles.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectRoleBinding.java @@ -16,7 +16,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.Project.ProjectPath; import org.dependencytrack.persistence.jooq.generated.tables.Role.RolePath; import org.dependencytrack.persistence.jooq.generated.tables.User.UserPath; -import org.dependencytrack.persistence.jooq.generated.tables.records.UsersProjectsRolesRecord; +import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectRoleBindingRecord; import org.jooq.Condition; import org.jooq.Field; import org.jooq.ForeignKey; @@ -51,69 +51,69 @@ comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) -public class UsersProjectsRoles extends TableImpl { +public class ProjectRoleBinding extends TableImpl { private static final long serialVersionUID = 622585294; /** - * The reference instance of USERS_PROJECTS_ROLES + * The reference instance of PROJECT_ROLE_BINDING */ - public static final UsersProjectsRoles USERS_PROJECTS_ROLES = new UsersProjectsRoles(); + public static final ProjectRoleBinding PROJECT_ROLE_BINDING = new ProjectRoleBinding(); /** * The class holding records for this type */ @Override - public Class getRecordType() { - return UsersProjectsRolesRecord.class; + public Class getRecordType() { + return ProjectRoleBindingRecord.class; } /** - * The column USERS_PROJECTS_ROLES.USER_ID. + * The column PROJECT_ROLE_BINDING.USER_ID. */ - public final TableField userId = createField(DSL.name("USER_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + public final TableField userId = createField(DSL.name("USER_ID"), SQLDataType.BIGINT.nullable(false), this, ""); /** - * The column USERS_PROJECTS_ROLES.PROJECT_ID. + * The column PROJECT_ROLE_BINDING.PROJECT_ID. */ - public final TableField projectId = createField(DSL.name("PROJECT_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + public final TableField projectId = createField(DSL.name("PROJECT_ID"), SQLDataType.BIGINT.nullable(false), this, ""); /** - * The column USERS_PROJECTS_ROLES.ROLE_ID. + * The column PROJECT_ROLE_BINDING.ROLE_ID. */ - public final TableField roleId = createField(DSL.name("ROLE_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + public final TableField roleId = createField(DSL.name("ROLE_ID"), SQLDataType.BIGINT.nullable(false), this, ""); - private UsersProjectsRoles(Name alias, Table aliased) { + private ProjectRoleBinding(Name alias, Table aliased) { this(alias, aliased, (Field[]) null, null); } - private UsersProjectsRoles(Name alias, Table aliased, Field[] parameters, Condition where) { + private ProjectRoleBinding(Name alias, Table aliased, Field[] parameters, Condition where) { super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); } /** - * Create an aliased USERS_PROJECTS_ROLES table reference + * Create an aliased PROJECT_ROLE_BINDING table reference */ - public UsersProjectsRoles(String alias) { - this(DSL.name(alias), USERS_PROJECTS_ROLES); + public ProjectRoleBinding(String alias) { + this(DSL.name(alias), PROJECT_ROLE_BINDING); } /** - * Create an aliased USERS_PROJECTS_ROLES table reference + * Create an aliased PROJECT_ROLE_BINDING table reference */ - public UsersProjectsRoles(Name alias) { - this(alias, USERS_PROJECTS_ROLES); + public ProjectRoleBinding(Name alias) { + this(alias, PROJECT_ROLE_BINDING); } /** - * Create a USERS_PROJECTS_ROLES table reference + * Create a PROJECT_ROLE_BINDING table reference */ - public UsersProjectsRoles() { - this(DSL.name("USERS_PROJECTS_ROLES"), null); + public ProjectRoleBinding() { + this(DSL.name("PROJECT_ROLE_BINDING"), null); } - public UsersProjectsRoles(Table path, ForeignKey childPath, InverseForeignKey parentPath) { - super(path, childPath, parentPath, USERS_PROJECTS_ROLES); + public ProjectRoleBinding(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath, PROJECT_ROLE_BINDING); } /** @@ -127,13 +127,13 @@ public UsersProjectsRoles(Table path, ForeignKey { + public static class UsersProjectsRolesPath extends ProjectRoleBinding implements Path { private static final long serialVersionUID = 622585294; - public UsersProjectsRolesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + public UsersProjectsRolesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } - private UsersProjectsRolesPath(Name alias, Table aliased) { + private UsersProjectsRolesPath(Name alias, Table aliased) { super(alias, aliased); } @@ -160,12 +160,12 @@ public Schema getSchema() { @Override public List getIndexes() { - return Arrays.asList(Indexes.USERS_PROJECTS_ROLES_ROLE_ID_IDX, Indexes.USERS_PROJECTS_ROLES_USER_PROJECT_IDX); + return Arrays.asList(Indexes.PROJECT_ROLE_BINDING_ROLE_ID_IDX, Indexes.PROJECT_ROLE_BINDING_USER_PROJECT_IDX); } @Override - public List> getReferences() { - return Arrays.asList(Keys.USERS_PROJECTS_ROLES_PROJECT_FK, Keys.USERS_PROJECTS_ROLES_ROLE_FK, Keys.USERS_PROJECTS_ROLES_USER_FK); + public List> getReferences() { + return Arrays.asList(Keys.PROJECT_ROLE_BINDING_PROJECT_FK, Keys.PROJECT_ROLE_BINDING_ROLE_FK, Keys.PROJECT_ROLE_BINDING_USER_FK); } private transient ProjectPath _project; @@ -175,7 +175,7 @@ public List getIndexes() { */ public ProjectPath project() { if (_project == null) - _project = new ProjectPath(this, Keys.USERS_PROJECTS_ROLES_PROJECT_FK, null); + _project = new ProjectPath(this, Keys.PROJECT_ROLE_BINDING_PROJECT_FK, null); return _project; } @@ -187,7 +187,7 @@ public ProjectPath project() { */ public RolePath role() { if (_role == null) - _role = new RolePath(this, Keys.USERS_PROJECTS_ROLES_ROLE_FK, null); + _role = new RolePath(this, Keys.PROJECT_ROLE_BINDING_ROLE_FK, null); return _role; } @@ -199,63 +199,63 @@ public RolePath role() { */ public UserPath user() { if (_user == null) - _user = new UserPath(this, Keys.USERS_PROJECTS_ROLES_USER_FK, null); + _user = new UserPath(this, Keys.PROJECT_ROLE_BINDING_USER_FK, null); return _user; } @Override - public UsersProjectsRoles as(String alias) { - return new UsersProjectsRoles(DSL.name(alias), this); + public ProjectRoleBinding as(String alias) { + return new ProjectRoleBinding(DSL.name(alias), this); } @Override - public UsersProjectsRoles as(Name alias) { - return new UsersProjectsRoles(alias, this); + public ProjectRoleBinding as(Name alias) { + return new ProjectRoleBinding(alias, this); } @Override - public UsersProjectsRoles as(Table alias) { - return new UsersProjectsRoles(alias.getQualifiedName(), this); + public ProjectRoleBinding as(Table alias) { + return new ProjectRoleBinding(alias.getQualifiedName(), this); } /** * Rename this table */ @Override - public UsersProjectsRoles rename(String name) { - return new UsersProjectsRoles(DSL.name(name), null); + public ProjectRoleBinding rename(String name) { + return new ProjectRoleBinding(DSL.name(name), null); } /** * Rename this table */ @Override - public UsersProjectsRoles rename(Name name) { - return new UsersProjectsRoles(name, null); + public ProjectRoleBinding rename(Name name) { + return new ProjectRoleBinding(name, null); } /** * Rename this table */ @Override - public UsersProjectsRoles rename(Table name) { - return new UsersProjectsRoles(name.getQualifiedName(), null); + public ProjectRoleBinding rename(Table name) { + return new ProjectRoleBinding(name.getQualifiedName(), null); } /** * Create an inline derived table from this table */ @Override - public UsersProjectsRoles where(Condition condition) { - return new UsersProjectsRoles(getQualifiedName(), aliased() ? this : null, null, condition); + public ProjectRoleBinding where(Condition condition) { + return new ProjectRoleBinding(getQualifiedName(), aliased() ? this : null, null, condition); } /** * Create an inline derived table from this table */ @Override - public UsersProjectsRoles where(Collection conditions) { + public ProjectRoleBinding where(Collection conditions) { return where(DSL.and(conditions)); } @@ -263,7 +263,7 @@ public UsersProjectsRoles where(Collection conditions) { * Create an inline derived table from this table */ @Override - public UsersProjectsRoles where(Condition... conditions) { + public ProjectRoleBinding where(Condition... conditions) { return where(DSL.and(conditions)); } @@ -271,7 +271,7 @@ public UsersProjectsRoles where(Condition... conditions) { * Create an inline derived table from this table */ @Override - public UsersProjectsRoles where(Field condition) { + public ProjectRoleBinding where(Field condition) { return where(DSL.condition(condition)); } @@ -280,7 +280,7 @@ public UsersProjectsRoles where(Field condition) { */ @Override @PlainSQL - public UsersProjectsRoles where(SQL condition) { + public ProjectRoleBinding where(SQL condition) { return where(DSL.condition(condition)); } @@ -289,7 +289,7 @@ public UsersProjectsRoles where(SQL condition) { */ @Override @PlainSQL - public UsersProjectsRoles where(@Stringly.SQL String condition) { + public ProjectRoleBinding where(@Stringly.SQL String condition) { return where(DSL.condition(condition)); } @@ -298,7 +298,7 @@ public UsersProjectsRoles where(@Stringly.SQL String condition) { */ @Override @PlainSQL - public UsersProjectsRoles where(@Stringly.SQL String condition, Object... binds) { + public ProjectRoleBinding where(@Stringly.SQL String condition, Object... binds) { return where(DSL.condition(condition, binds)); } @@ -307,7 +307,7 @@ public UsersProjectsRoles where(@Stringly.SQL String condition, Object... binds) */ @Override @PlainSQL - public UsersProjectsRoles where(@Stringly.SQL String condition, QueryPart... parts) { + public ProjectRoleBinding where(@Stringly.SQL String condition, QueryPart... parts) { return where(DSL.condition(condition, parts)); } @@ -315,7 +315,7 @@ public UsersProjectsRoles where(@Stringly.SQL String condition, QueryPart... par * Create an inline derived table from this table */ @Override - public UsersProjectsRoles whereExists(Select select) { + public ProjectRoleBinding whereExists(Select select) { return where(DSL.exists(select)); } @@ -323,7 +323,7 @@ public UsersProjectsRoles whereExists(Select select) { * Create an inline derived table from this table */ @Override - public UsersProjectsRoles whereNotExists(Select select) { + public ProjectRoleBinding whereNotExists(Select select) { return where(DSL.notExists(select)); } } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java index 8092f464a2..fbd3f4dd97 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java @@ -15,7 +15,7 @@ import org.dependencytrack.persistence.jooq.generated.Keys; import org.dependencytrack.persistence.jooq.generated.tables.Permission.PermissionPath; import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions.RolesPermissionsPath; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles.UsersProjectsRolesPath; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding.UsersProjectsRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.records.RoleRecord; import org.jooq.Condition; import org.jooq.Field; @@ -191,11 +191,11 @@ public RolesPermissionsPath rolesPermissions() { /** * Get the implicit to-many join path to the - * USERS_PROJECTS_ROLES table + * PROJECT_ROLE_BINDING table */ public UsersProjectsRolesPath usersProjectsRoles() { if (_usersProjectsRoles == null) - _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.USERS_PROJECTS_ROLES_ROLE_FK.getInverseKey()); + _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.PROJECT_ROLE_BINDING_ROLE_FK.getInverseKey()); return _usersProjectsRoles; } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java index 3505e8d1ab..bddbb87ed0 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java @@ -18,7 +18,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.Team.TeamPath; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions.UserProjectEffectivePermissionsPath; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions.UsersPermissionsPath; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles.UsersProjectsRolesPath; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding.UsersProjectsRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams.UsersTeamsPath; import org.dependencytrack.persistence.jooq.generated.tables.records.UserRecord; import org.jooq.Check; @@ -256,11 +256,11 @@ public UsersPermissionsPath usersPermissions() { /** * Get the implicit to-many join path to the - * USERS_PROJECTS_ROLES table + * PROJECT_ROLE_BINDING table */ public UsersProjectsRolesPath usersProjectsRoles() { if (_usersProjectsRoles == null) - _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.USERS_PROJECTS_ROLES_USER_FK.getInverseKey()); + _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.PROJECT_ROLE_BINDING_USER_FK.getInverseKey()); return _usersProjectsRoles; } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersProjectsRolesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRoleBindingRecord.java similarity index 61% rename from persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersProjectsRolesRecord.java rename to persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRoleBindingRecord.java index ff32879bcf..c3609f91c1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersProjectsRolesRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRoleBindingRecord.java @@ -6,7 +6,7 @@ import javax.annotation.processing.Generated; -import org.dependencytrack.persistence.jooq.generated.tables.UsersProjectsRoles; +import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.jooq.impl.TableRecordImpl; @@ -22,50 +22,50 @@ comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) -public class UsersProjectsRolesRecord extends TableRecordImpl { +public class ProjectRoleBindingRecord extends TableRecordImpl { private static final long serialVersionUID = -147063056; /** - * Setter for USERS_PROJECTS_ROLES.USER_ID. + * Setter for PROJECT_ROLE_BINDING.USER_ID. */ - public UsersProjectsRolesRecord setUserId(Long value) { + public ProjectRoleBindingRecord setUserId(Long value) { set(0, value); return this; } /** - * Getter for USERS_PROJECTS_ROLES.USER_ID. + * Getter for PROJECT_ROLE_BINDING.USER_ID. */ public Long getUserId() { return (Long) get(0); } /** - * Setter for USERS_PROJECTS_ROLES.PROJECT_ID. + * Setter for PROJECT_ROLE_BINDING.PROJECT_ID. */ - public UsersProjectsRolesRecord setProjectId(Long value) { + public ProjectRoleBindingRecord setProjectId(Long value) { set(1, value); return this; } /** - * Getter for USERS_PROJECTS_ROLES.PROJECT_ID. + * Getter for PROJECT_ROLE_BINDING.PROJECT_ID. */ public Long getProjectId() { return (Long) get(1); } /** - * Setter for USERS_PROJECTS_ROLES.ROLE_ID. + * Setter for PROJECT_ROLE_BINDING.ROLE_ID. */ - public UsersProjectsRolesRecord setRoleId(Long value) { + public ProjectRoleBindingRecord setRoleId(Long value) { set(2, value); return this; } /** - * Getter for USERS_PROJECTS_ROLES.ROLE_ID. + * Getter for PROJECT_ROLE_BINDING.ROLE_ID. */ public Long getRoleId() { return (Long) get(2); @@ -78,15 +78,15 @@ public Long getRoleId() { /** * Create a detached UsersProjectsRolesRecord */ - public UsersProjectsRolesRecord() { - super(UsersProjectsRoles.USERS_PROJECTS_ROLES); + public ProjectRoleBindingRecord() { + super(ProjectRoleBinding.PROJECT_ROLE_BINDING); } /** * Create a detached, initialised UsersProjectsRolesRecord */ - public UsersProjectsRolesRecord(Long userId, Long projectId, Long roleId) { - super(UsersProjectsRoles.USERS_PROJECTS_ROLES); + public ProjectRoleBindingRecord(Long userId, Long projectId, Long roleId) { + super(ProjectRoleBinding.PROJECT_ROLE_BINDING); setUserId(userId); setProjectId(projectId); diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index d80df826f3..d634bea3b5 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -34,7 +34,7 @@ - + @@ -42,7 +42,7 @@ - + UPDATE "PROJECT" SET "AUTHORS" = JSON_BUILD_ARRAY(JSON_BUILD_OBJECT('name', "AUTHOR"))::TEXT @@ -61,7 +61,7 @@ - + @@ -146,7 +146,7 @@ - + UPDATE "PROJECT" SET "INACTIVE_SINCE" = NOW() WHERE "ACTIVE" IS FALSE @@ -218,19 +218,19 @@ - + - + - + + + 9:75a5b859b6131f15a841804da10c14dc + + + SET CONSTRAINTS ALL IMMEDIATE + CREATE OR REPLACE FUNCTION remove_duplicate_rows( table_name TEXT, @@ -1206,7 +1222,7 @@ $q$, table_name, table_name, column_1, column_1, column_2, column_2 ); END; - $$ LANGUAGE plpgsql; + $$ LANGUAGE plpgsql; @@ -1229,7 +1245,7 @@ - DO $$ + DO $$ BEGIN PERFORM remove_duplicate_rows('APIKEYS_TEAMS', 'TEAM_ID', 'APIKEY_ID'); PERFORM remove_duplicate_rows('LDAPUSERS_PERMISSIONS', 'LDAPUSER_ID', 'PERMISSION_ID'); @@ -1242,8 +1258,6 @@ PERFORM remove_duplicate_rows('TEAMS_PERMISSIONS', 'TEAM_ID', 'PERMISSION_ID'); END $$; - - DROP FUNCTION remove_duplicate_rows; @@ -1266,7 +1280,7 @@ -- Loop over each team name group that has duplicates. FOR rec IN SELECT - "NAME", + "NAME" AS name, MIN("ID") AS canonical_id, ARRAY_AGG("ID") AS all_ids FROM "TEAM" @@ -1300,6 +1314,14 @@ $delete$, dup_id); END LOOP; END LOOP; + + PERFORM remove_duplicate_rows('APIKEYS_TEAMS', 'TEAM_ID', 'APIKEY_ID'); + PERFORM remove_duplicate_rows('LDAPUSERS_TEAMS', 'TEAM_ID', 'LDAPUSER_ID'); + PERFORM remove_duplicate_rows('MANAGEDUSERS_TEAMS', 'TEAM_ID', 'MANAGEDUSER_ID'); + PERFORM remove_duplicate_rows('NOTIFICATIONRULE_TEAMS', 'NOTIFICATIONRULE_ID', 'TEAM_ID'); + PERFORM remove_duplicate_rows('OIDCUSERS_TEAMS', 'TEAM_ID', 'OIDCUSERS_ID'); + PERFORM remove_duplicate_rows('TEAMS_PERMISSIONS', 'TEAM_ID', 'PERMISSION_ID'); + DROP FUNCTION remove_duplicate_rows; END $$; @@ -1432,6 +1454,15 @@ + + 9:aa6e0cecae0b4f050a56eb1bbcb686be + @@ -1604,8 +1635,17 @@ + WITH cte_created_user AS ( + INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "DN") + SELECT 'LDAP', "USERNAME", "EMAIL", "DN" + FROM "LDAPUSER" + ON CONFLICT ("USERNAME") DO NOTHING + RETURNING "USERNAME" + ) INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "DN") - SELECT 'LDAP', "USERNAME", "EMAIL", "DN" FROM "LDAPUSER"; + SELECT 'LDAP', ("USERNAME" || '-CONFLICT-LDAP') AS "USERNAME", "EMAIL", "DN" + FROM "LDAPUSER" + WHERE "USERNAME" NOT IN (SELECT "USERNAME" FROM cte_created_user); INSERT INTO "USERS_PERMISSIONS" ("PERMISSION_ID", "USER_ID") SELECT "LDAPUSERS_PERMISSIONS"."PERMISSION_ID" @@ -1614,7 +1654,8 @@ INNER JOIN "LDAPUSER" ON "LDAPUSER"."ID" = "LDAPUSERS_PERMISSIONS"."LDAPUSER_ID" INNER JOIN "USER" - ON "USER"."USERNAME" = "LDAPUSER"."USERNAME" + ON ("USER"."USERNAME" = "LDAPUSER"."USERNAME" + OR "USER"."USERNAME" = ("LDAPUSER"."USERNAME" || '-CONFLICT-LDAP')) AND "USER"."TYPE" = 'LDAP' ON CONFLICT ("PERMISSION_ID", "USER_ID") DO NOTHING; @@ -1625,15 +1666,25 @@ INNER JOIN "LDAPUSER" ON "LDAPUSER"."ID" = "LDAPUSERS_TEAMS"."LDAPUSER_ID" INNER JOIN "USER" - ON "USER"."USERNAME" = "LDAPUSER"."USERNAME" + ON ("USER"."USERNAME" = "LDAPUSER"."USERNAME" + OR "USER"."USERNAME" = ("LDAPUSER"."USERNAME" || '-CONFLICT-LDAP')) AND "USER"."TYPE" = 'LDAP' ON CONFLICT ("TEAM_ID", "USER_ID") DO NOTHING; + WITH cte_created_user AS ( + INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER") + SELECT 'OIDC', "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER" + FROM "OIDCUSER" + ON CONFLICT ("USERNAME") DO NOTHING + RETURNING "USERNAME" + ) INSERT INTO "USER" ("TYPE", "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER") - SELECT 'OIDC', "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER" FROM "OIDCUSER"; + SELECT 'OIDC', ("USERNAME" || '-CONFLICT-OIDC') AS "USERNAME", "EMAIL", "SUBJECT_IDENTIFIER" + FROM "OIDCUSER" + WHERE "USERNAME" NOT IN (SELECT "USERNAME" FROM cte_created_user); INSERT INTO "USERS_PERMISSIONS" ("PERMISSION_ID", "USER_ID") SELECT "OIDCUSERS_PERMISSIONS"."PERMISSION_ID" @@ -1642,7 +1693,8 @@ INNER JOIN "OIDCUSER" ON "OIDCUSER"."ID" = "OIDCUSERS_PERMISSIONS"."OIDCUSER_ID" INNER JOIN "USER" - ON "USER"."USERNAME" = "OIDCUSER"."USERNAME" + ON ("USER"."USERNAME" = "OIDCUSER"."USERNAME" + OR "USER"."USERNAME" = ("OIDCUSER"."USERNAME" || '-CONFLICT-OIDC')) AND "USER"."TYPE" = 'OIDC' ON CONFLICT ("PERMISSION_ID", "USER_ID") DO NOTHING; @@ -1653,7 +1705,8 @@ INNER JOIN "OIDCUSER" ON "OIDCUSER"."ID" = "OIDCUSERS_TEAMS"."OIDCUSERS_ID" INNER JOIN "USER" - ON "USER"."USERNAME" = "OIDCUSER"."USERNAME" + ON ("USER"."USERNAME" = "OIDCUSER"."USERNAME" + OR "USER"."USERNAME" = ("OIDCUSER"."USERNAME" || '-CONFLICT-OIDC')) AND "USER"."TYPE" = 'OIDC' ON CONFLICT ("TEAM_ID", "USER_ID") DO NOTHING; @@ -2334,10 +2387,10 @@ - + @@ -2345,7 +2398,7 @@ @@ -2353,19 +2406,19 @@ - + - + @@ -2385,7 +2438,7 @@ INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" ("USER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" - FROM "USERS_PROJECTS_ROLES" upr + FROM "PROJECT_ROLE_BINDING" upr INNER JOIN "ROLES_PERMISSIONS" rp ON rp."ROLE_ID" = upr."ROLE_ID" INNER JOIN "PERMISSION" p @@ -2411,14 +2464,14 @@ INTO project_ids FROM ( SELECT upr."PROJECT_ID" - FROM "USERS_PROJECTS_ROLES" upr + FROM "PROJECT_ROLE_BINDING" upr INNER JOIN old_table ON old_table."ROLE_ID" = upr."ROLE_ID" ) sub; ELSE SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") INTO project_ids - FROM "USERS_PROJECTS_ROLES" + FROM "PROJECT_ROLE_BINDING" WHERE "ROLE_ID" = ANY(role_ids); END IF; @@ -2444,14 +2497,14 @@ INTO project_ids FROM ( SELECT upr."PROJECT_ID" - FROM "USERS_PROJECTS_ROLES" upr + FROM "PROJECT_ROLE_BINDING" upr INNER JOIN new_table ON new_table."ROLE_ID" = upr."ROLE_ID" ) sub; ELSE SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") INTO project_ids - FROM "USERS_PROJECTS_ROLES" + FROM "PROJECT_ROLE_BINDING" WHERE "ROLE_ID" = ANY(role_ids); END IF; @@ -2481,7 +2534,7 @@ INTO project_ids FROM ( SELECT upr."PROJECT_ID" - FROM "USERS_PROJECTS_ROLES" upr + FROM "PROJECT_ROLE_BINDING" upr INNER JOIN new_table ON new_table."ROLE_ID" = upr."ROLE_ID" FULL OUTER JOIN old_table @@ -2490,7 +2543,7 @@ ELSE SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") INTO project_ids - FROM "USERS_PROJECTS_ROLES" + FROM "PROJECT_ROLE_BINDING" WHERE "ROLE_ID" = ANY(role_ids); END IF; @@ -2501,23 +2554,23 @@ - -- INSERT trigger for USERS_PROJECTS_ROLES + -- INSERT trigger for PROJECT_ROLE_BINDING CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_insert - AFTER INSERT ON "USERS_PROJECTS_ROLES" + AFTER INSERT ON "PROJECT_ROLE_BINDING" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); - -- DELETE trigger for USERS_PROJECTS_ROLES + -- DELETE trigger for PROJECT_ROLE_BINDING CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_delete - AFTER DELETE ON "USERS_PROJECTS_ROLES" + AFTER DELETE ON "PROJECT_ROLE_BINDING" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); - -- UPDATE trigger for USERS_PROJECTS_ROLES + -- UPDATE trigger for PROJECT_ROLE_BINDING CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_update - AFTER UPDATE ON "USERS_PROJECTS_ROLES" + AFTER UPDATE ON "PROJECT_ROLE_BINDING" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_update(); From a00331403ba98ab9d3ed44e4fb6c162edc69404c Mon Sep 17 00:00:00 2001 From: jhoward-lm <140011346+jhoward-lm@users.noreply.github.com> Date: Wed, 28 May 2025 14:11:17 -0500 Subject: [PATCH 30/45] refactor: migrate JDBI methods to query manager (#27) - revert: unintended changelog formatting - refactor: change column indexes to table primary keys - refactor: rename PROJECT_ROLE_BINDING to USER_PROJECT_ROLES - refactor: rename ProjectRoleBinding class to UserProjectRole - chore: regenerate jooq Signed-off-by: Jonathan Howard --- .../java/org/dependencytrack/model/Role.java | 1 - ...tRoleBinding.java => UserProjectRole.java} | 19 +- .../persistence/QueryManager.java | 24 +- .../persistence/RoleQueryManager.java | 162 +++++++-- .../persistence/jdbi/RoleDao.java | 124 ------- .../mapping/ProjectRoleRowBindingMapper.java | 76 ---- .../resources/v1/AccessControlResource.java | 15 +- .../resources/v1/PermissionResource.java | 24 +- .../resources/v1/RoleResource.java | 8 +- .../resources/v1/UserResource.java | 49 +-- .../main/resources/META-INF/persistence.xml | 2 +- .../persistence/RoleQueryManagerTest.java | 30 +- .../resources/v1/RoleResourceTest.java | 8 +- .../v1/UserResourceAuthenticatedTest.java | 8 +- .../jooq/generated/DefaultSchema.java | 16 +- .../persistence/jooq/generated/Indexes.java | 8 +- .../persistence/jooq/generated/Keys.java | 17 +- .../persistence/jooq/generated/Routines.java | 2 +- .../persistence/jooq/generated/Tables.java | 12 +- .../jooq/generated/enums/Severity.java | 2 +- .../generated/routines/CalcRiskScore.java | 4 +- .../generated/routines/HasProjectAccess.java | 4 +- .../generated/routines/JsonbVulnAliases.java | 4 +- ...RecalcUserProjectEffectivePermissions.java | 4 +- ...lcUserProjectRoleEffectivePermissions.java | 4 +- .../routines/UpdateComponentMetrics.java | 4 +- .../routines/UpdatePortfolioMetrics.java | 4 +- .../routines/UpdateProjectMetrics.java | 4 +- .../tables/AffectedVersionAttribution.java | 8 +- .../jooq/generated/tables/Analysis.java | 8 +- .../generated/tables/AnalysisComment.java | 8 +- .../jooq/generated/tables/ApiKey.java | 8 +- .../jooq/generated/tables/ApiKeysTeams.java | 8 +- .../jooq/generated/tables/Bom.java | 8 +- .../jooq/generated/tables/Component.java | 8 +- .../generated/tables/ComponentOccurrence.java | 8 +- .../generated/tables/ComponentProperty.java | 8 +- .../tables/ComponentsVulnerabilities.java | 8 +- .../jooq/generated/tables/ConfigProperty.java | 4 +- .../generated/tables/DependencyMetrics.java | 8 +- .../jooq/generated/tables/Epss.java | 4 +- .../generated/tables/FindingAttribution.java | 8 +- .../generated/tables/IntegrityAnalysis.java | 8 +- .../tables/IntegrityMetaComponent.java | 4 +- .../jooq/generated/tables/License.java | 8 +- .../jooq/generated/tables/LicenseGroup.java | 8 +- .../generated/tables/LicenseGroupLicense.java | 8 +- .../generated/tables/MappedLdapGroup.java | 8 +- .../generated/tables/MappedOidcGroup.java | 8 +- .../tables/NotificationPublisher.java | 8 +- .../generated/tables/NotificationRule.java | 8 +- .../tables/NotificationRuleProjects.java | 8 +- .../tables/NotificationRuleTags.java | 8 +- .../tables/NotificationRuleTeams.java | 8 +- .../jooq/generated/tables/OidcGroup.java | 8 +- .../jooq/generated/tables/Permission.java | 8 +- .../jooq/generated/tables/Policy.java | 8 +- .../generated/tables/PolicyCondition.java | 8 +- .../jooq/generated/tables/PolicyProjects.java | 8 +- .../jooq/generated/tables/PolicyTags.java | 8 +- .../generated/tables/PolicyViolation.java | 8 +- .../generated/tables/PortfolioMetrics.java | 4 +- .../jooq/generated/tables/Project.java | 24 +- .../generated/tables/ProjectAccessTeams.java | 8 +- .../generated/tables/ProjectHierarchy.java | 8 +- .../generated/tables/ProjectMetadata.java | 8 +- .../jooq/generated/tables/ProjectMetrics.java | 8 +- .../generated/tables/ProjectProperty.java | 8 +- .../generated/tables/ProjectRoleBinding.java | 329 ------------------ .../jooq/generated/tables/ProjectsTags.java | 8 +- .../jooq/generated/tables/Repository.java | 4 +- .../tables/RepositoryMetaComponent.java | 4 +- .../jooq/generated/tables/Role.java | 24 +- .../generated/tables/RolesPermissions.java | 19 +- .../generated/tables/ServiceComponent.java | 8 +- .../ServiceComponentsVulnerabilities.java | 8 +- .../jooq/generated/tables/Tag.java | 8 +- .../jooq/generated/tables/Team.java | 8 +- .../generated/tables/TeamsPermissions.java | 8 +- .../jooq/generated/tables/User.java | 36 +- .../UserProjectEffectivePermissions.java | 8 +- .../generated/tables/UserProjectRoles.java | 328 +++++++++++++++++ .../generated/tables/UsersPermissions.java | 8 +- .../jooq/generated/tables/UsersTeams.java | 8 +- .../jooq/generated/tables/Vex.java | 8 +- .../generated/tables/ViolationAnalysis.java | 8 +- .../tables/ViolationAnalysisComment.java | 8 +- .../generated/tables/VulnerabilitiesTags.java | 8 +- .../jooq/generated/tables/Vulnerability.java | 8 +- .../generated/tables/VulnerabilityAlias.java | 4 +- .../tables/VulnerabilityMetrics.java | 4 +- .../generated/tables/VulnerabilityPolicy.java | 8 +- .../tables/VulnerabilityPolicyBundle.java | 4 +- .../generated/tables/VulnerabilityScan.java | 4 +- .../generated/tables/VulnerableSoftware.java | 8 +- .../VulnerableSoftwareVulnerabilities.java | 8 +- .../jooq/generated/tables/WorkflowState.java | 8 +- .../AffectedVersionAttributionRecord.java | 4 +- .../tables/records/AnalysisCommentRecord.java | 4 +- .../tables/records/AnalysisRecord.java | 4 +- .../tables/records/ApiKeyRecord.java | 4 +- .../tables/records/ApiKeysTeamsRecord.java | 4 +- .../generated/tables/records/BomRecord.java | 4 +- .../records/ComponentOccurrenceRecord.java | 4 +- .../records/ComponentPropertyRecord.java | 4 +- .../tables/records/ComponentRecord.java | 4 +- .../ComponentsVulnerabilitiesRecord.java | 4 +- .../tables/records/ConfigPropertyRecord.java | 4 +- .../records/DependencyMetricsRecord.java | 10 +- .../generated/tables/records/EpssRecord.java | 4 +- .../records/FindingAttributionRecord.java | 4 +- .../records/IntegrityAnalysisRecord.java | 4 +- .../records/IntegrityMetaComponentRecord.java | 4 +- .../records/LicenseGroupLicenseRecord.java | 4 +- .../tables/records/LicenseGroupRecord.java | 4 +- .../tables/records/LicenseRecord.java | 4 +- .../tables/records/MappedLdapGroupRecord.java | 4 +- .../tables/records/MappedOidcGroupRecord.java | 4 +- .../records/NotificationPublisherRecord.java | 4 +- .../NotificationRuleProjectsRecord.java | 4 +- .../records/NotificationRuleRecord.java | 4 +- .../records/NotificationRuleTagsRecord.java | 4 +- .../records/NotificationRuleTeamsRecord.java | 4 +- .../tables/records/OidcGroupRecord.java | 4 +- .../tables/records/PermissionRecord.java | 4 +- .../tables/records/PolicyConditionRecord.java | 4 +- .../tables/records/PolicyProjectsRecord.java | 4 +- .../tables/records/PolicyRecord.java | 4 +- .../tables/records/PolicyTagsRecord.java | 4 +- .../tables/records/PolicyViolationRecord.java | 4 +- .../records/PortfolioMetricsRecord.java | 4 +- .../records/ProjectAccessTeamsRecord.java | 4 +- .../records/ProjectHierarchyRecord.java | 4 +- .../tables/records/ProjectMetadataRecord.java | 4 +- .../tables/records/ProjectMetricsRecord.java | 4 +- .../tables/records/ProjectPropertyRecord.java | 4 +- .../tables/records/ProjectRecord.java | 4 +- .../records/ProjectRoleBindingRecord.java | 96 ----- .../tables/records/ProjectsTagsRecord.java | 4 +- .../RepositoryMetaComponentRecord.java | 4 +- .../tables/records/RepositoryRecord.java | 4 +- .../generated/tables/records/RoleRecord.java | 4 +- .../records/RolesPermissionsRecord.java | 18 +- .../records/ServiceComponentRecord.java | 4 +- ...erviceComponentsVulnerabilitiesRecord.java | 4 +- .../generated/tables/records/TagRecord.java | 4 +- .../generated/tables/records/TeamRecord.java | 4 +- .../records/TeamsPermissionsRecord.java | 4 +- ...UserProjectEffectivePermissionsRecord.java | 4 +- .../records/UserProjectRolesRecord.java | 106 ++++++ .../generated/tables/records/UserRecord.java | 4 +- .../records/UsersPermissionsRecord.java | 4 +- .../tables/records/UsersTeamsRecord.java | 4 +- .../generated/tables/records/VexRecord.java | 4 +- .../ViolationAnalysisCommentRecord.java | 4 +- .../records/ViolationAnalysisRecord.java | 4 +- .../records/VulnerabilitiesTagsRecord.java | 4 +- .../records/VulnerabilityAliasRecord.java | 4 +- .../records/VulnerabilityMetricsRecord.java | 4 +- .../VulnerabilityPolicyBundleRecord.java | 4 +- .../records/VulnerabilityPolicyRecord.java | 4 +- .../tables/records/VulnerabilityRecord.java | 4 +- .../records/VulnerabilityScanRecord.java | 4 +- .../records/VulnerableSoftwareRecord.java | 4 +- ...lnerableSoftwareVulnerabilitiesRecord.java | 4 +- .../tables/records/WorkflowStateRecord.java | 4 +- .../resources/migration/changelog-v5.6.0.xml | 112 +++--- 167 files changed, 1171 insertions(+), 1294 deletions(-) rename apiserver/src/main/java/org/dependencytrack/model/{ProjectRoleBinding.java => UserProjectRole.java} (84%) delete mode 100644 apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java delete mode 100644 apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowBindingMapper.java delete mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectRoleBinding.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectRoles.java delete mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRoleBindingRecord.java create mode 100644 persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectRolesRecord.java diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 2d282f0923..8cee1170eb 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -88,7 +88,6 @@ public enum FetchGroup { private String name; @Persistent(table = "ROLES_PERMISSIONS", defaultFetchGroup = "true") - @Unique(name = "ROLES_PERMISSIONS_IDX") @Join(column = "ROLE_ID") @Element(column = "PERMISSION_ID") private Set permissions = new LinkedHashSet<>(); diff --git a/apiserver/src/main/java/org/dependencytrack/model/ProjectRoleBinding.java b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java similarity index 84% rename from apiserver/src/main/java/org/dependencytrack/model/ProjectRoleBinding.java rename to apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java index 380b0c0369..cc69aefd1d 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/ProjectRoleBinding.java +++ b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java @@ -31,12 +31,12 @@ import java.util.stream.Stream; import javax.jdo.annotations.Column; +import javax.jdo.annotations.Element; import javax.jdo.annotations.Extension; -import javax.jdo.annotations.FetchGroup; import javax.jdo.annotations.Order; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.Persistent; -import javax.jdo.annotations.Unique; +import javax.jdo.annotations.PrimaryKey; /** * Base class for user-project-role mapping. @@ -44,15 +44,14 @@ * @author Jonathan Howard * @since 5.6.0 */ -@PersistenceCapable(table = "PROJECT_ROLE_BINDING") +@PersistenceCapable(table = "USER_PROJECT_ROLES") @JsonInclude(JsonInclude.Include.NON_NULL) -@Unique(name = "PROJECT_ROLE_BINDING_COMPOSITE_IDX", members = { "users", "project", "role" }) -@FetchGroup(name = "ALL", members = { - @Persistent(name = "role"), - @Persistent(name = "project"), - @Persistent(name = "users") +@PrimaryKey(name = "USER_PROJECT_ROLES_PK", columns = { + @Column(name = "USER_ID"), + @Column(name = "PROJECT_ID"), + @Column(name = "ROLE_ID") }) -public class ProjectRoleBinding implements Serializable { +public class UserProjectRole implements Serializable { @Persistent(defaultFetchGroup = "true") @Column(name = "ROLE_ID", allowsNull = "false") @@ -63,7 +62,7 @@ public class ProjectRoleBinding implements Serializable { private Project project; @Persistent(defaultFetchGroup = "true") - @Column(name = "USER_ID", allowsNull = "false") + @Element(column = "USER_ID") @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) private List users; diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index fadb3b01e2..f27bf35f1c 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -67,13 +67,13 @@ import org.dependencytrack.model.PolicyViolation; import org.dependencytrack.model.Project; import org.dependencytrack.model.ProjectProperty; -import org.dependencytrack.model.ProjectRoleBinding; import org.dependencytrack.model.Repository; import org.dependencytrack.model.RepositoryMetaComponent; import org.dependencytrack.model.RepositoryType; import org.dependencytrack.model.Role; import org.dependencytrack.model.ServiceComponent; import org.dependencytrack.model.Tag; +import org.dependencytrack.model.UserProjectRole; import org.dependencytrack.model.Vex; import org.dependencytrack.model.ViolationAnalysis; import org.dependencytrack.model.ViolationAnalysisComment; @@ -488,19 +488,19 @@ public QueryManager withL2CacheDisabled() { } /** - * Get the IDs of the {@link ProjectRoleBinding}s a given {@link Principal} is a member of. + * Get the IDs of the {@link UserProjectRole}s a given {@link Principal} is a member of. * - * @return A {@link Set} of {@link ProjectRoleBinding} IDs + * @return A {@link Set} of {@link UserProjectRole} IDs */ protected Set getRoleIds(final Principal principal, final Project project) { - final Query query = pm.newQuery(ProjectRoleBinding.class) + final Query query = pm.newQuery(UserProjectRole.class) .filter("project.id == :projectId && users.contains(:principal)") .setNamedParameters(Map.ofEntries( Map.entry("principal", principal), Map.entry("projectId", project.getId()))); return Set.of(executeAndCloseList(query).stream() - .map(ProjectRoleBinding::getRole) + .map(UserProjectRole::getRole) .map(Role::getId) .toArray(Long[]::new)); } @@ -870,6 +870,10 @@ public Role createRole(final String name, final List permissions) { return getRoleQueryManager().createRole(name, permissions); } + public boolean addPermissionToRole(final Role role, final Permission permission) { + return getRoleQueryManager().addPermissionToRole(role, permission); + } + public List getRoles() { return getRoleQueryManager().getRoles(); } @@ -1137,15 +1141,11 @@ public List getUnassignedProjects(final String username) { return getRoleQueryManager().getUnassignedProjects(username); } - public List getUnassignedProjects(final User user) { - return getRoleQueryManager().getUnassignedProjects(user); - } - public List getUnassignedRolePermissions(final Role role) { return getRoleQueryManager().getUnassignedRolePermissions(role); } - public List getUserRoles(final User user) { + public List getUserRoles(final User user) { return getRoleQueryManager().getUserRoles(user); } @@ -1153,6 +1153,10 @@ public boolean removeRoleFromUser(final User user, final Role role, final Projec return getRoleQueryManager().removeRoleFromUser(user, role, project); } + public boolean userProjectRoleExists(final User user, final Role role, final Project project) { + return getRoleQueryManager().userProjectRoleExists(user, role, project); + } + public NotificationRule createNotificationRule(String name, NotificationScope scope, NotificationLevel level, NotificationPublisher publisher) { return getNotificationQueryManager().createNotificationRule(name, scope, level, publisher); } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index b15ee5fb69..0f8d908312 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -18,19 +18,21 @@ */ package org.dependencytrack.persistence; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.jdo.PersistenceManager; import javax.jdo.Query; +import javax.jdo.datastore.JDOConnection; import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; -import org.dependencytrack.model.ProjectRoleBinding; -import org.dependencytrack.persistence.jdbi.JdbiFactory; -import org.dependencytrack.persistence.jdbi.RoleDao; +import org.dependencytrack.model.UserProjectRole; import org.apache.commons.lang3.StringUtils; @@ -53,16 +55,37 @@ final class RoleQueryManager extends QueryManager implements IQueryManager { @Override public Role createRole(final String name, final List permissions) { - return callInTransaction(() -> { - final Role role = new Role(); - role.setName(name); - role.setPermissions(Set.copyOf(permissions)); + final Role role = new Role(); + role.setName(name); + role.setPermissions(Set.copyOf(permissions)); - LOGGER.debug(name + " role created with permissions: " - + String.join(", ", permissions.stream().map(Permission::getName).toList())); + LOGGER.debug("%s role created with permissions: %s".formatted( + name, permissions.stream().map(Permission::getName).collect(Collectors.joining(", ")))); - return persist(role); - }); + return persist(role); + } + + @Override + public boolean addPermissionToRole(final Role role, final Permission permission) { + Query query = pm.newQuery(Query.SQL, /* language=sql */ """ + SELECT EXISTS( + SELECT 1 + FROM "ROLES_PERMISSIONS" + WHERE "ROLE_ID" = ? + AND "PERMISSION_ID" = ? + ) + """) + .setParameters(role.getId(), permission.getId()); + + if (executeAndCloseResultUnique(query, Boolean.class)) + return false; + + role.addPermissions(permission); + persist(role); + + LOGGER.debug("Permission '%s' added to role '%s'".formatted(permission.getName(), role.getName())); + + return true; } @Override @@ -81,7 +104,7 @@ public Role getRoleByName(final String name) { final String role = StringUtils.lowerCase(StringUtils.trimToNull(name)); final Query query = pm.newQuery(Role.class) .filter("name.toLowerCase().trim() == :name") - .setNamedParameters(Map.of("name", role)) + .setParameters(role) .range(0, 1); return executeAndCloseUnique(query); @@ -93,18 +116,33 @@ public Role getRole(final String uuid) { } @Override - public List getUserRoles(final User user) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class) - .getUserRoles(user.getUsername())); + public List getUserRoles(final User user) { + final Query query = pm.newQuery(Query.SQL, /* language=sql */ """ + SELECT upr."USER_ID", upr."PROJECT_ID", upr."ROLE_ID" + FROM "USER_PROJECT_ROLES" upr + INNER JOIN "USER" u + ON u."ID" = upr."USER_ID" + WHERE u."USERNAME" = ? + """) + .setParameters(user.getUsername()); + + return executeAndCloseResultList(query, UserProjectRole.class); } public List getUnassignedProjects(final String username) { - return getUnassignedProjects(getUser(username)); - } - - public List getUnassignedProjects(final User user) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class) - .getUserUnassignedProjects(user.getUsername())); + final Query query = pm.newQuery(Query.SQL, /* language=sql */ """ + SELECT p."ID", p."NAME", p."VERSION", p."UUID" + FROM "PROJECT" p + LEFT JOIN "USER_PROJECT_ROLES" upr + ON upr."PROJECT_ID" = p."ID" + LEFT JOIN "USER" u + ON u."ID" = upr."USER_ID" + WHERE u."USERNAME" != ? + OR u."USERNAME" IS NULL + """) + .setParameters(username); + + return executeAndCloseResultList(query, Project.class); } public List getUnassignedRolePermissions(final Role role) { @@ -116,7 +154,7 @@ public List getUnassignedRolePermissions(final Role role) { final Query query = pm.newQuery(Permission.class) .filter("!:permissionNames.contains(name)") - .setNamedParameters(Map.of("permissionNames", permissionNames)); + .setParameters(permissionNames); permissions.addAll(executeAndCloseList(query)); @@ -136,19 +174,79 @@ public Role updateRole(final Role transientRole) { @Override public boolean addRoleToUser(final User user, final Role role, final Project project) { - return JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser( - user.getId(), - project.getId(), - role.getId())) == 1; + Query query = pm.newQuery(Query.SQL, /* language=sql */ """ + SELECT EXISTS( + SELECT 1 + FROM "USER_PROJECT_ROLES" + WHERE "USER_ID" = ? + AND "PROJECT_ID" = ? + AND "ROLE_ID" = ? + ) + """) + .setParameters(user.getId(), project.getId(), role.getId()); + + if (executeAndCloseResultUnique(query, Boolean.class)) + return false; + + final JDOConnection jdoConnection = pm.getDataStoreConnection(); + final var nativeConnection = (Connection) jdoConnection.getNativeConnection(); + + try (final PreparedStatement ps = nativeConnection.prepareStatement( + /* language=sql */ """ + INSERT INTO "USER_PROJECT_ROLES" + ("USER_ID", "PROJECT_ID", "ROLE_ID") + VALUES + (?, ?, ?) + """)) { + ps.setLong(1, user.getId()); + ps.setLong(2, project.getId()); + ps.setLong(3, role.getId()); + ps.execute(); + } catch (SQLException e) { + throw new RuntimeException("Failed to add role: user='%s' / project='%s' / role='%s'".formatted( + user.getUsername(), project.toString(), role.getName()), e); + } finally { + jdoConnection.close(); + } + + return true; } @Override public boolean removeRoleFromUser(final User user, final Role role, final Project project) { - return JdbiFactory.withJdbiHandle(handle -> handle.attach(RoleDao.class).removeRoleFromUser( - user.getId(), - project.getName(), - role.getId())) > 0; + final Query query = pm.newQuery(Query.SQL, /* language=sql */ """ + SELECT * + FROM "USER_PROJECT_ROLES" + WHERE "USER_ID" = ? + AND "PROJECT_ID" = ? + AND "ROLE_ID" = ? + """) + .setParameters(user.getId(), project.getId(), role.getId()); + + final UserProjectRole projectRole = executeAndCloseResultUnique(query, UserProjectRole.class); + + if (projectRole == null) + return false; + + delete(projectRole); + + return true; + } + + @Override + public boolean userProjectRoleExists(final User user, final Role role, final Project project) { + Query query = pm.newQuery(Query.SQL, /* language=sql */ """ + SELECT EXISTS( + SELECT 1 + FROM "USER_PROJECT_ROLES" + WHERE "USER_ID" = ? + AND "PROJECT_ID" = ? + AND "ROLE_ID" = ? + ) + """) + .setParameters(user.getId(), project.getId(), role.getId()); + + return executeAndCloseResultUnique(query, Boolean.class); } } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java deleted file mode 100644 index 19d87c5b3b..0000000000 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/RoleDao.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.persistence.jdbi; - -import java.util.List; - -import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRoleBinding; -import org.dependencytrack.persistence.jdbi.mapping.ProjectRoleRowBindingMapper; - -import org.jdbi.v3.sqlobject.config.RegisterFieldMapper; -import org.jdbi.v3.sqlobject.config.RegisterRowMapper; -import org.jdbi.v3.sqlobject.customizer.Bind; -import org.jdbi.v3.sqlobject.statement.SqlQuery; -import org.jdbi.v3.sqlobject.statement.SqlUpdate; - -/** - * @since 5.6.0 - */ -public interface RoleDao { - - @SqlUpdate(/* language=sql */ """ - DELETE - FROM "ROLE" - WHERE "ID" = :roleId - """) - int deleteRole(@Bind final long roleId); - - @SqlUpdate(/* language=sql */ """ - INSERT INTO "ROLES_PERMISSIONS" - ("ROLE_ID", "PERMISSION_ID") - VALUES - (:roleId, :permissionId) - ON CONFLICT DO NOTHING - """) - int addPermissionToRole(@Bind long roleId, @Bind long permissionId); - - @SqlUpdate(/* language=sql */ """ - INSERT INTO "PROJECT_ROLE_BINDING" - ("USER_ID", "PROJECT_ID", "ROLE_ID") - VALUES - (:userId, :projectId, :roleId) - ON CONFLICT ("USER_ID", "PROJECT_ID") DO - UPDATE SET "ROLE_ID" = EXCLUDED."ROLE_ID" - """) - int addRoleToUser(@Bind long userId, @Bind long projectId, @Bind long roleId); - - @SqlUpdate(/* language=sql */ """ - DELETE - FROM "PROJECT_ROLE_BINDING" - WHERE "USER_ID" = :userId - AND "ROLE_ID" = :roleId - AND "PROJECT_ID" IN ( - SELECT "ID" - FROM "PROJECT" - WHERE "NAME" = :projectName - ) - """) - int removeRoleFromUser(@Bind long userId, @Bind String projectName, @Bind long roleId); - - @SqlQuery(/* language=sql */ """ - SELECT - p."ID" AS "PROJECT_ID", - p."NAME" AS "PROJECT_NAME", - p."UUID" AS "PROJECT_UUID", - r."ID" AS "ROLE_ID", - r."NAME" AS "ROLE_NAME", - r."UUID" AS "ROLE_UUID", - u."ID" AS "USER_ID", - u."USERNAME" AS "USER_NAME", - u."TYPE" AS "USER_TYPE" - FROM "PROJECT" p - INNER JOIN "PROJECT_ROLE_BINDING" pr - ON pr."PROJECT_ID" = p."ID" - INNER JOIN "USER" u - ON u."ID" = pr."USER_ID" - INNER JOIN "ROLE" r - ON r."ID" = pr."ROLE_ID" - WHERE u."USERNAME" = :username - """) - @RegisterRowMapper(ProjectRoleRowBindingMapper.class) - List getUserRoles(@Bind String username); - - @SqlQuery(/* language=sql */ """ - SELECT EXISTS ( - SELECT 1 - FROM "PROJECT_ROLE_BINDING" - WHERE "ROLE_ID" = :roleId - AND "PROJECT_ID" = :projectId - AND "USER_ID" = :userId - ) - """) - boolean userProjectRoleBindingExists(@Bind long userId, @Bind long projectId, @Bind long roleId); - - @SqlQuery(/* language=sql */ """ - SELECT p."ID", p."NAME", p."UUID" - FROM "PROJECT" p - LEFT JOIN "PROJECT_ROLE_BINDING" pr - ON pr."PROJECT_ID" = p."ID" - LEFT JOIN "USER" u - ON u."ID" = pr."USER_ID" - WHERE u."USERNAME" != :username - OR u."USERNAME" IS NULL - """) - @RegisterFieldMapper(Project.class) - List getUserUnassignedProjects(@Bind String username); - -} diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowBindingMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowBindingMapper.java deleted file mode 100644 index faeade58d5..0000000000 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRoleRowBindingMapper.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.persistence.jdbi.mapping; - -import alpine.model.LdapUser; -import alpine.model.ManagedUser; -import alpine.model.OidcUser; -import alpine.model.User; - -import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRoleBinding; -import org.dependencytrack.model.Role; - -import org.jdbi.v3.core.mapper.RowMapper; -import org.jdbi.v3.core.statement.StatementContext; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.UUID; - -import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.maybeSet; - -public class ProjectRoleRowBindingMapper implements RowMapper { - - public ProjectRoleBinding map(final ResultSet resultSet, final StatementContext ctx) throws SQLException { - final ProjectRoleBinding projectRole = new ProjectRoleBinding(); - projectRole.setProject(new Project()); - projectRole.setRole(new Role()); - - final String type = resultSet.getString("USER_TYPE"); - final User user = switch (type) { - case "LDAP" -> new LdapUser(); - case "MANAGED" -> new ManagedUser(); - case "OIDC" -> new OidcUser(); - default -> null; - }; - - if (user == null) - return projectRole; - - maybeSet(resultSet, "USER_ID", ResultSet::getLong, user::setId); - maybeSet(resultSet, "USER_NAME", ResultSet::getString, user::setUsername); - projectRole.addUsers(user); - - maybeSet(resultSet, "PROJECT_ID", ResultSet::getLong, projectRole.getProject()::setId); - maybeSet(resultSet, "PROJECT_NAME", ResultSet::getString, projectRole.getProject()::setName); - maybeSet(resultSet, "PROJECT_UUID", ResultSet::getString, value -> { - projectRole.getProject().setUuid(UUID.fromString(value)); - }); - - maybeSet(resultSet, "ROLE_ID", ResultSet::getLong, projectRole.getRole()::setId); - maybeSet(resultSet, "ROLE_NAME", ResultSet::getString, projectRole.getRole()::setName); - maybeSet(resultSet, "ROLE_UUID", ResultSet::getString, value -> { - projectRole.getRole().setUuid(UUID.fromString(value)); - }); - - return projectRole; - } - -} diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index 41fc390d0e..c2d98db4e4 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -54,10 +54,6 @@ import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import org.dependencytrack.persistence.jdbi.RoleDao; -import org.jdbi.v3.core.Handle; - -import static org.dependencytrack.persistence.jdbi.JdbiFactory.openJdbiHandle; import java.util.List; import java.util.NoSuchElementException; @@ -142,15 +138,12 @@ public Response retrieveUserProjects( if (user == null) return Response.status(Response.Status.NOT_FOUND).build(); - try (final Handle jdbiHandle = openJdbiHandle(getAlpineRequest())) { - var dao = jdbiHandle.attach(RoleDao.class); - List projects = dao.getUserUnassignedProjects(user.getUsername()); + List projects = qm.getUnassignedProjects(username); - if (projects == null || projects.isEmpty()) - return Response.noContent().build(); + if (projects == null || projects.isEmpty()) + return Response.noContent().build(); - return Response.ok(projects).header(TOTAL_COUNT_HEADER, projects.size()).build(); - } + return Response.ok(projects).header(TOTAL_COUNT_HEADER, projects.size()).build(); } } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java index d85b5f6bd5..8c1bf66b5c 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java @@ -298,22 +298,20 @@ public Response addPermissionToRole( @PathParam("permission") String permissionName) { try (QueryManager qm = new QueryManager()) { Role role = qm.getObjectByUuid(Role.class, uuid); - if (role == null) { + if (role == null) return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); - } + final Permission permission = qm.getPermission(permissionName); - if (permission == null) { + if (permission == null) return Response.status(Response.Status.NOT_FOUND).entity("The permission could not be found.").build(); - } - final Set permissions = role.getPermissions(); - if (permissions != null && !permissions.contains(permission)) { - permissions.add(permission); - role.setPermissions(permissions); - role = qm.persist(role); - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added permission for role: " + role.getName() + " / permission: " + permission.getName()); - return Response.ok(role).build(); - } - return Response.status(Response.Status.NOT_MODIFIED).build(); + + if (!qm.addPermissionToRole(role, permission)) + return Response.status(Response.Status.NOT_MODIFIED).build(); + + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, + "Added permission for role: " + role.getName() + " / permission: " + permission.getName()); + + return Response.ok(role).build(); } } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index 2b1c107d6f..e41661cdd2 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -46,9 +46,9 @@ import jakarta.ws.rs.core.Response; import org.dependencytrack.auth.Permissions; -import org.dependencytrack.model.validation.ValidUuid; import org.dependencytrack.model.Role; -import org.dependencytrack.model.ProjectRoleBinding; +import org.dependencytrack.model.UserProjectRole; +import org.dependencytrack.model.validation.ValidUuid; import org.dependencytrack.persistence.QueryManager; import org.dependencytrack.resources.v1.vo.CreateRoleRequest; @@ -246,7 +246,7 @@ public Response deleteRole( @ApiResponse( responseCode = "200", description = "A list of roles assigned to the user", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProjectRoleBinding.class)))), + content = @Content(array = @ArraySchema(schema = @Schema(implementation = UserProjectRole.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) @@ -260,7 +260,7 @@ public Response getUserRoles( return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); } - List roles = qm.getUserRoles(user); + List roles = qm.getUserRoles(user); if (roles == null || roles.isEmpty()) { LOGGER.info("No roles found for user: " + username); return Response.ok(List.of()).build(); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 6d3df4681c..05b9e6b2e9 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -78,8 +78,6 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import javax.jdo.Query; -import org.dependencytrack.persistence.jdbi.JdbiFactory; -import org.dependencytrack.persistence.jdbi.RoleDao; import java.security.Principal; import java.util.ArrayList; import java.util.Collections; @@ -878,7 +876,7 @@ private UserSubject buildUserSubject(final String username, final String email) ) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) - public Response assignProjectRoleBindingToUser( + public Response assignProjectRoleToUser( @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); @@ -900,9 +898,8 @@ public Response assignProjectRoleBindingToUser( return problem.toResponse(); } - boolean exists = JdbiFactory.withJdbiHandle(getAlpineRequest(), handle -> handle.attach(RoleDao.class) - .userProjectRoleBindingExists(user.getId(), project.getId(), role.getId())); - if (exists) return Response.notModified().build(); + if (qm.userProjectRoleExists(user, role, project)) + return Response.notModified().build(); qm.addRoleToUser(user, role, project); @@ -937,7 +934,7 @@ public Response assignProjectRoleBindingToUser( ) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) - public Response removeProjectRoleBindingFromUser( + public Response removeProjectRoleFromUser( @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); @@ -987,9 +984,8 @@ public Response setUserTeams( @Parameter(description = "The UUID(s) of the team(s) to associate username with", required = true) @Valid TeamsSetRequest request) { try (QueryManager qm = new QueryManager()) { User user = qm.getUser(username); - if (user == null) { + if (user == null) return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); - } // Compare given team uuids against current user teams final Set currentUserTeams = user.getTeams() == null ? Collections.emptySet() @@ -998,34 +994,41 @@ public Response setUserTeams( .map(UUID::toString) .collect(Collectors.toSet()); - if (currentUserTeams.equals(request.teams())) { + if (currentUserTeams.equals(request.teams())) return Response.notModified().entity("The user is already a member of the selected team(s)").build(); - } - List requestedTeams = request.teams() - .stream() - .map(uuid -> qm.getObjectByUuid(Team.class, uuid)) - .toList(); + final Query query = qm.getPersistenceManager().newQuery(Team.class) + .filter(":uuids.contains(uuid)") + .setNamedParameters(Map.of("uuids", request.teams())); + + final List requestedTeams; - // check that all requested teams exist - List notFound = new ArrayList<>(); - for (int i = 0; i < requestedTeams.size(); i++) { - if (requestedTeams.get(i) == null) - notFound.add(request.teams().stream().toList().get(i)); + try { + requestedTeams = query.executeList(); + } finally { + query.closeAll(); } + // Check that all requested teams exist + List notFound = requestedTeams.stream() + .map(Team::getName) + .filter(name -> !request.teams().contains(name)) + .toList(); + if (notFound.size() > 0) { - // String msg = String.format("One or more teams could not be found:\n%s", ); Map response = new HashMap<>(); response.put("error", "One or more teams could not be found"); response.put("teams", notFound); + return Response.status(Response.Status.BAD_REQUEST).entity(response).build(); } user.setTeams(requestedTeams); qm.persist(user); - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, - "Added team membership for: " + user.getUsername() + " / team: " + requestedTeams.toString()); + + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added team membership for: %s / team: %s" + .formatted(user.getUsername(), requestedTeams.toString())); + return Response.ok(user).build(); } } diff --git a/apiserver/src/main/resources/META-INF/persistence.xml b/apiserver/src/main/resources/META-INF/persistence.xml index 261c4d1fb6..1e1e712a05 100644 --- a/apiserver/src/main/resources/META-INF/persistence.xml +++ b/apiserver/src/main/resources/META-INF/persistence.xml @@ -54,12 +54,12 @@ org.dependencytrack.model.Project org.dependencytrack.model.ProjectMetadata org.dependencytrack.model.ProjectProperty - org.dependencytrack.model.ProjectRoleBinding org.dependencytrack.model.Repository org.dependencytrack.model.RepositoryMetaComponent org.dependencytrack.model.Role org.dependencytrack.model.ServiceComponent org.dependencytrack.model.Tag + org.dependencytrack.model.UserProjectRole org.dependencytrack.model.Vex org.dependencytrack.model.ViolationAnalysis org.dependencytrack.model.ViolationAnalysisComment diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 5ebbfed820..380f37ff66 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -19,10 +19,8 @@ package org.dependencytrack.persistence; import org.dependencytrack.model.Project; -import org.dependencytrack.model.ProjectRoleBinding; import org.dependencytrack.model.Role; -import org.dependencytrack.persistence.jdbi.JdbiFactory; -import org.dependencytrack.persistence.jdbi.RoleDao; +import org.dependencytrack.model.UserProjectRole; import alpine.model.ManagedUser; import alpine.model.Permission; @@ -135,13 +133,9 @@ public void testGetUserRoles() throws ParseException { expectedRole.setName("maintainer"); qm.persist(expectedRole); - JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getId(), - testProject.getId(), - expectedRole.getId())); + qm.addRoleToUser(testUser, expectedRole, testProject); - List actualRoles = qm.getUserRoles(testUser); + List actualRoles = qm.getUserRoles(testUser); Assert.assertEquals(actualRoles.size(), 1); Assert.assertEquals(expectedRole.toString(), actualRoles.get(0).getRole().toString()); @@ -180,16 +174,9 @@ public void testGetUnassignedProjects() throws ParseException { unassignedProject2.setName("test-project-3"); qm.persist(unassignedProject2); - JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getId(), - assignedProject.getId(), - maintainerRole.getId())); - - List expectedProjects = Arrays.asList( - unassignedProject1, - unassignedProject2); + qm.addRoleToUser(testUser, maintainerRole, assignedProject); + List expectedProjects = Arrays.asList(unassignedProject1, unassignedProject2); List actualProjects = qm.getUnassignedProjects(testUserName); // Sort both lists by project name before asserting equivalence @@ -320,12 +307,7 @@ public void testRemoveRoleFromUser() throws ParseException { maintainerRole.setName("maintainer"); qm.persist(maintainerRole); - JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getId(), - testProject.getId(), - maintainerRole.getId())); - + qm.addRoleToUser(testUser, maintainerRole, testProject); Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); } diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java index 5f49f57cf6..51f4f2279e 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -31,8 +31,6 @@ import org.dependencytrack.ResourceTest; import org.dependencytrack.auth.Permissions; import org.dependencytrack.persistence.DefaultObjectGenerator; -import org.dependencytrack.persistence.jdbi.JdbiFactory; -import org.dependencytrack.persistence.jdbi.RoleDao; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; @@ -172,11 +170,7 @@ public void getUserRolesTest() throws ParseException { expectedRole.setName("maintainer"); qm.persist(expectedRole); - JdbiFactory.withJdbiHandle( - handle -> handle.attach(RoleDao.class).addRoleToUser( - testUser.getId(), - testProject.getId(), - expectedRole.getId())); + qm.addRoleToUser(testUser, expectedRole, testProject); Response response = jersey.target(V1_ROLE + "/test-user/roles").request() .header(X_API_KEY, apiKey) diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java index 8c6fce7a92..afadc885a6 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java @@ -754,7 +754,7 @@ public void setUserTeamsInvalidTest() { } @Test - public void assignProjectRoleBindingToUserTest() { + public void assignProjectRoleToUserTest() { // Arrange ManagedUser user = qm.createManagedUser("roleuser", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( @@ -783,7 +783,7 @@ public void assignProjectRoleBindingToUserTest() { } @Test - public void assignProjectRoleBindingToUserAlreadyAssignedTest() { + public void assignProjectRoleToUserAlreadyAssignedTest() { ManagedUser user = qm.createManagedUser("roleuser2", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( "Test Project 2","null", @@ -807,7 +807,7 @@ public void assignProjectRoleBindingToUserAlreadyAssignedTest() { } @Test - public void removeProjectRoleBindingFromUserTest() { + public void removeProjectRoleFromUserTest() { ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( "Test Project 3","null", @@ -831,7 +831,7 @@ public void removeProjectRoleBindingFromUserTest() { } @Test - public void removeProjectRoleBindingFromUserNotAssignedTest() { + public void removeProjectRoleFromUserNotAssignedTest() { ManagedUser user = qm.createManagedUser("roleuser4", TEST_USER_PASSWORD_HASH); Project project = qm.createProject( "Test Project 4","null", diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java index e77b7cb481..a8e945e899 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/DefaultSchema.java @@ -61,8 +61,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.TeamsPermissions; import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; +import org.dependencytrack.persistence.jooq.generated.tables.UserProjectRoles; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -90,14 +90,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class DefaultSchema extends SchemaImpl { - private static final long serialVersionUID = -1575785433; + private static final long serialVersionUID = 1027843848; /** * The reference instance of DEFAULT_SCHEMA @@ -365,14 +365,14 @@ public class DefaultSchema extends SchemaImpl { public final UserProjectEffectivePermissions USER_PROJECT_EFFECTIVE_PERMISSIONS = UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS; /** - * The table USERS_PERMISSIONS. + * The table USER_PROJECT_ROLES. */ - public final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; + public final UserProjectRoles USER_PROJECT_ROLES = UserProjectRoles.USER_PROJECT_ROLES; /** - * The table PROJECT_ROLE_BINDING. + * The table USERS_PERMISSIONS. */ - public final ProjectRoleBinding PROJECT_ROLE_BINDING = ProjectRoleBinding.PROJECT_ROLE_BINDING; + public final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; /** * The table USERS_TEAMS. @@ -512,8 +512,8 @@ public final List> getTables() { TeamsPermissions.TEAMS_PERMISSIONS, User.USER, UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, + UserProjectRoles.USER_PROJECT_ROLES, UsersPermissions.USERS_PERMISSIONS, - ProjectRoleBinding.PROJECT_ROLE_BINDING, UsersTeams.USERS_TEAMS, Vex.VEX, ViolationAnalysis.VIOLATIONANALYSIS, diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java index f619370fe5..8afb6bdad1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Indexes.java @@ -34,12 +34,10 @@ import org.dependencytrack.persistence.jooq.generated.tables.ProjectMetadata; import org.dependencytrack.persistence.jooq.generated.tables.Repository; import org.dependencytrack.persistence.jooq.generated.tables.RepositoryMetaComponent; -import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponent; import org.dependencytrack.persistence.jooq.generated.tables.ServiceComponentsVulnerabilities; import org.dependencytrack.persistence.jooq.generated.tables.Tag; import org.dependencytrack.persistence.jooq.generated.tables.User; -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysisComment; @@ -62,7 +60,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @@ -149,8 +147,6 @@ public class Indexes { public static final Index REPOSITORY_META_COMPONENT_COMPOUND_IDX = Internal.createIndex(DSL.name("REPOSITORY_META_COMPONENT_COMPOUND_IDX"), RepositoryMetaComponent.REPOSITORY_META_COMPONENT, new OrderField[] { RepositoryMetaComponent.REPOSITORY_META_COMPONENT.repositoryType, RepositoryMetaComponent.REPOSITORY_META_COMPONENT.namespace, RepositoryMetaComponent.REPOSITORY_META_COMPONENT.name }, true); public static final Index REPOSITORY_META_COMPONENT_LASTCHECK_IDX = Internal.createIndex(DSL.name("REPOSITORY_META_COMPONENT_LASTCHECK_IDX"), RepositoryMetaComponent.REPOSITORY_META_COMPONENT, new OrderField[] { RepositoryMetaComponent.REPOSITORY_META_COMPONENT.lastCheck }, false); public static final Index REPOSITORY_UUID_IDX = Internal.createIndex(DSL.name("REPOSITORY_UUID_IDX"), Repository.REPOSITORY, new OrderField[] { Repository.REPOSITORY.uuid }, false); - public static final Index ROLES_PERMISSIONS_PERMISSION_ID_IDX = Internal.createIndex(DSL.name("ROLES_PERMISSIONS_PERMISSION_ID_IDX"), RolesPermissions.ROLES_PERMISSIONS, new OrderField[] { RolesPermissions.ROLES_PERMISSIONS.permissionId }, false); - public static final Index ROLES_PERMISSIONS_ROLE_ID_IDX = Internal.createIndex(DSL.name("ROLES_PERMISSIONS_ROLE_ID_IDX"), RolesPermissions.ROLES_PERMISSIONS, new OrderField[] { RolesPermissions.ROLES_PERMISSIONS.roleId }, false); public static final Index SERVICECOMPONENT_LAST_RISKSCORE_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENT_LAST_RISKSCORE_IDX"), ServiceComponent.SERVICECOMPONENT, new OrderField[] { ServiceComponent.SERVICECOMPONENT.lastRiskScore }, false); public static final Index SERVICECOMPONENT_PARENT_SERVICECOMPONENT_ID_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENT_PARENT_SERVICECOMPONENT_ID_IDX"), ServiceComponent.SERVICECOMPONENT, new OrderField[] { ServiceComponent.SERVICECOMPONENT.parentServiceComponentId }, false); public static final Index SERVICECOMPONENT_PROJECT_ID_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENT_PROJECT_ID_IDX"), ServiceComponent.SERVICECOMPONENT, new OrderField[] { ServiceComponent.SERVICECOMPONENT.projectId }, false); @@ -158,8 +154,6 @@ public class Indexes { public static final Index SERVICECOMPONENTS_VULNERABILITIES_VULNERABILITY_ID_IDX = Internal.createIndex(DSL.name("SERVICECOMPONENTS_VULNERABILITIES_VULNERABILITY_ID_IDX"), ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES, new OrderField[] { ServiceComponentsVulnerabilities.SERVICECOMPONENTS_VULNERABILITIES.vulnerabilityId }, false); public static final Index TAG_NAME_IDX = Internal.createIndex(DSL.name("TAG_NAME_IDX"), Tag.TAG, new OrderField[] { Tag.TAG.name }, true); public static final Index USER_USERNAME_IDX = Internal.createIndex(DSL.name("USER_USERNAME_IDX"), User.USER, new OrderField[] { User.USER.username }, true); - public static final Index PROJECT_ROLE_BINDING_ROLE_ID_IDX = Internal.createIndex(DSL.name("PROJECT_ROLE_BINDING_ROLE_ID_IDX"), ProjectRoleBinding.PROJECT_ROLE_BINDING, new OrderField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.roleId }, false); - public static final Index PROJECT_ROLE_BINDING_USER_PROJECT_IDX = Internal.createIndex(DSL.name("PROJECT_ROLE_BINDING_USER_PROJECT_IDX"), ProjectRoleBinding.PROJECT_ROLE_BINDING, new OrderField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.userId, ProjectRoleBinding.PROJECT_ROLE_BINDING.projectId }, true); public static final Index VEX_PROJECT_ID_IDX = Internal.createIndex(DSL.name("VEX_PROJECT_ID_IDX"), Vex.VEX, new OrderField[] { Vex.VEX.projectId }, false); public static final Index VIOLATIONANALYSIS_COMPONENT_ID_IDX = Internal.createIndex(DSL.name("VIOLATIONANALYSIS_COMPONENT_ID_IDX"), ViolationAnalysis.VIOLATIONANALYSIS, new OrderField[] { ViolationAnalysis.VIOLATIONANALYSIS.componentId }, false); public static final Index VIOLATIONANALYSIS_POLICYVIOLATION_ID_IDX = Internal.createIndex(DSL.name("VIOLATIONANALYSIS_POLICYVIOLATION_ID_IDX"), ViolationAnalysis.VIOLATIONANALYSIS, new OrderField[] { ViolationAnalysis.VIOLATIONANALYSIS.policyViolationId }, false); diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java index e3ee7ee646..39d68a31df 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Keys.java @@ -58,8 +58,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.TeamsPermissions; import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; +import org.dependencytrack.persistence.jooq.generated.tables.UserProjectRoles; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -125,9 +125,9 @@ import org.dependencytrack.persistence.jooq.generated.tables.records.TeamRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.TeamsPermissionsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UserProjectEffectivePermissionsRecord; +import org.dependencytrack.persistence.jooq.generated.tables.records.UserProjectRolesRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UserRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UsersPermissionsRecord; -import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectRoleBindingRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.UsersTeamsRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.VexRecord; import org.dependencytrack.persistence.jooq.generated.tables.records.ViolationAnalysisCommentRecord; @@ -158,7 +158,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @@ -184,7 +184,7 @@ public class Keys { public static final UniqueKey COMPONENT_PROPERTY_PK = Internal.createUniqueKey(ComponentProperty.COMPONENT_PROPERTY, DSL.name("COMPONENT_PROPERTY_PK"), new TableField[] { ComponentProperty.COMPONENT_PROPERTY.id }, true); public static final UniqueKey CONFIGPROPERTY_PK = Internal.createUniqueKey(ConfigProperty.CONFIGPROPERTY, DSL.name("CONFIGPROPERTY_PK"), new TableField[] { ConfigProperty.CONFIGPROPERTY.id }, true); public static final UniqueKey CONFIGPROPERTY_U1 = Internal.createUniqueKey(ConfigProperty.CONFIGPROPERTY, DSL.name("CONFIGPROPERTY_U1"), new TableField[] { ConfigProperty.CONFIGPROPERTY.groupName, ConfigProperty.CONFIGPROPERTY.propertyName }, true); - public static final UniqueKey DEPENDENCYMETRICS_PK = Internal.createUniqueKey(DependencyMetrics.DEPENDENCYMETRICS, DSL.name("DEPENDENCYMETRICS_PK"), new TableField[] { DependencyMetrics.DEPENDENCYMETRICS.projectId, DependencyMetrics.DEPENDENCYMETRICS.componentId, DependencyMetrics.DEPENDENCYMETRICS.lastOccurrence }, true); + public static final UniqueKey DEPENDENCYMETRICS_PK = Internal.createUniqueKey(DependencyMetrics.DEPENDENCYMETRICS, DSL.name("DEPENDENCYMETRICS_PK"), new TableField[] { DependencyMetrics.DEPENDENCYMETRICS.componentId, DependencyMetrics.DEPENDENCYMETRICS.lastOccurrence }, true); public static final UniqueKey EPSS_CVE_KEY = Internal.createUniqueKey(Epss.EPSS, DSL.name("EPSS_CVE_key"), new TableField[] { Epss.EPSS.cve }, true); public static final UniqueKey EPSS_CVE_PK = Internal.createUniqueKey(Epss.EPSS, DSL.name("EPSS_CVE_PK"), new TableField[] { Epss.EPSS.id }, true); public static final UniqueKey FINDINGATTRIBUTION_PK = Internal.createUniqueKey(FindingAttribution.FINDINGATTRIBUTION, DSL.name("FINDINGATTRIBUTION_PK"), new TableField[] { FindingAttribution.FINDINGATTRIBUTION.id }, true); @@ -234,7 +234,7 @@ public class Keys { public static final UniqueKey ROLE_NAME_IDX = Internal.createUniqueKey(Role.ROLE, DSL.name("ROLE_NAME_IDX"), new TableField[] { Role.ROLE.name }, true); public static final UniqueKey ROLE_PK = Internal.createUniqueKey(Role.ROLE, DSL.name("ROLE_PK"), new TableField[] { Role.ROLE.id }, true); public static final UniqueKey ROLE_UUID_IDX = Internal.createUniqueKey(Role.ROLE, DSL.name("ROLE_UUID_IDX"), new TableField[] { Role.ROLE.uuid }, true); - public static final UniqueKey ROLES_PERMISSIONS_COMPOSITE_IDX = Internal.createUniqueKey(RolesPermissions.ROLES_PERMISSIONS, DSL.name("ROLES_PERMISSIONS_COMPOSITE_IDX"), new TableField[] { RolesPermissions.ROLES_PERMISSIONS.roleId, RolesPermissions.ROLES_PERMISSIONS.permissionId }, true); + public static final UniqueKey ROLES_PERMISSIONS_PK = Internal.createUniqueKey(RolesPermissions.ROLES_PERMISSIONS, DSL.name("ROLES_PERMISSIONS_PK"), new TableField[] { RolesPermissions.ROLES_PERMISSIONS.roleId, RolesPermissions.ROLES_PERMISSIONS.permissionId }, true); public static final UniqueKey SERVICECOMPONENT_PK = Internal.createUniqueKey(ServiceComponent.SERVICECOMPONENT, DSL.name("SERVICECOMPONENT_PK"), new TableField[] { ServiceComponent.SERVICECOMPONENT.id }, true); public static final UniqueKey SERVICECOMPONENT_UUID_IDX = Internal.createUniqueKey(ServiceComponent.SERVICECOMPONENT, DSL.name("SERVICECOMPONENT_UUID_IDX"), new TableField[] { ServiceComponent.SERVICECOMPONENT.uuid }, true); public static final UniqueKey TAG_PK = Internal.createUniqueKey(Tag.TAG, DSL.name("TAG_PK"), new TableField[] { Tag.TAG.id }, true); @@ -244,6 +244,7 @@ public class Keys { public static final UniqueKey TEAMS_PERMISSIONS_PK = Internal.createUniqueKey(TeamsPermissions.TEAMS_PERMISSIONS, DSL.name("TEAMS_PERMISSIONS_PK"), new TableField[] { TeamsPermissions.TEAMS_PERMISSIONS.teamId, TeamsPermissions.TEAMS_PERMISSIONS.permissionId }, true); public static final UniqueKey USER_PK = Internal.createUniqueKey(User.USER, DSL.name("USER_PK"), new TableField[] { User.USER.id }, true); public static final UniqueKey USER_PROJECT_EFFECTIVE_PERMISSIONS_PK = Internal.createUniqueKey(UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, DSL.name("USER_PROJECT_EFFECTIVE_PERMISSIONS_PK"), new TableField[] { UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.projectId, UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.userId, UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.permissionId }, true); + public static final UniqueKey USER_PROJECT_ROLES_PK = Internal.createUniqueKey(UserProjectRoles.USER_PROJECT_ROLES, DSL.name("USER_PROJECT_ROLES_PK"), new TableField[] { UserProjectRoles.USER_PROJECT_ROLES.userId, UserProjectRoles.USER_PROJECT_ROLES.projectId, UserProjectRoles.USER_PROJECT_ROLES.roleId }, true); public static final UniqueKey USERS_PERMISSIONS_PK = Internal.createUniqueKey(UsersPermissions.USERS_PERMISSIONS, DSL.name("USERS_PERMISSIONS_PK"), new TableField[] { UsersPermissions.USERS_PERMISSIONS.userId, UsersPermissions.USERS_PERMISSIONS.permissionId }, true); public static final UniqueKey USERS_TEAMS_PK = Internal.createUniqueKey(UsersTeams.USERS_TEAMS, DSL.name("USERS_TEAMS_PK"), new TableField[] { UsersTeams.USERS_TEAMS.userId, UsersTeams.USERS_TEAMS.teamId }, true); public static final UniqueKey VEX_PK = Internal.createUniqueKey(Vex.VEX, DSL.name("VEX_PK"), new TableField[] { Vex.VEX.id }, true); @@ -336,11 +337,11 @@ public class Keys { public static final ForeignKey USER_PROJECT_EFFECTIVE_PERMISSIONS_PERMISSION_NAME_FK = Internal.createForeignKey(UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, DSL.name("USER_PROJECT_EFFECTIVE_PERMISSIONS_PERMISSION_NAME_FK"), new TableField[] { UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.permissionName }, Keys.PERMISSION_IDX, new TableField[] { Permission.PERMISSION.name }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USER_PROJECT_EFFECTIVE_PERMISSIONS_PROJECT_FK = Internal.createForeignKey(UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, DSL.name("USER_PROJECT_EFFECTIVE_PERMISSIONS_PROJECT_FK"), new TableField[] { UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USER_PROJECT_EFFECTIVE_PERMISSIONS_USER_FK = Internal.createForeignKey(UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS, DSL.name("USER_PROJECT_EFFECTIVE_PERMISSIONS_USER_FK"), new TableField[] { UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey USER_PROJECT_ROLES_PROJECT_FK = Internal.createForeignKey(UserProjectRoles.USER_PROJECT_ROLES, DSL.name("USER_PROJECT_ROLES_PROJECT_FK"), new TableField[] { UserProjectRoles.USER_PROJECT_ROLES.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey USER_PROJECT_ROLES_ROLE_FK = Internal.createForeignKey(UserProjectRoles.USER_PROJECT_ROLES, DSL.name("USER_PROJECT_ROLES_ROLE_FK"), new TableField[] { UserProjectRoles.USER_PROJECT_ROLES.roleId }, Keys.ROLE_PK, new TableField[] { Role.ROLE.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); + public static final ForeignKey USER_PROJECT_ROLES_USER_FK = Internal.createForeignKey(UserProjectRoles.USER_PROJECT_ROLES, DSL.name("USER_PROJECT_ROLES_USER_FK"), new TableField[] { UserProjectRoles.USER_PROJECT_ROLES.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_PERMISSIONS_PERMISSION_FK = Internal.createForeignKey(UsersPermissions.USERS_PERMISSIONS, DSL.name("USERS_PERMISSIONS_PERMISSION_FK"), new TableField[] { UsersPermissions.USERS_PERMISSIONS.permissionId }, Keys.PERMISSION_PK, new TableField[] { Permission.PERMISSION.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_PERMISSIONS_USER_FK = Internal.createForeignKey(UsersPermissions.USERS_PERMISSIONS, DSL.name("USERS_PERMISSIONS_USER_FK"), new TableField[] { UsersPermissions.USERS_PERMISSIONS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); - public static final ForeignKey PROJECT_ROLE_BINDING_PROJECT_FK = Internal.createForeignKey(ProjectRoleBinding.PROJECT_ROLE_BINDING, DSL.name("PROJECT_ROLE_BINDING_PROJECT_FK"), new TableField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); - public static final ForeignKey PROJECT_ROLE_BINDING_ROLE_FK = Internal.createForeignKey(ProjectRoleBinding.PROJECT_ROLE_BINDING, DSL.name("PROJECT_ROLE_BINDING_ROLE_FK"), new TableField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.roleId }, Keys.ROLE_PK, new TableField[] { Role.ROLE.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); - public static final ForeignKey PROJECT_ROLE_BINDING_USER_FK = Internal.createForeignKey(ProjectRoleBinding.PROJECT_ROLE_BINDING, DSL.name("PROJECT_ROLE_BINDING_USER_FK"), new TableField[] { ProjectRoleBinding.PROJECT_ROLE_BINDING.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_TEAMS_TEAM_FK = Internal.createForeignKey(UsersTeams.USERS_TEAMS, DSL.name("USERS_TEAMS_TEAM_FK"), new TableField[] { UsersTeams.USERS_TEAMS.teamId }, Keys.TEAM_PK, new TableField[] { Team.TEAM.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey USERS_TEAMS_USER_FK = Internal.createForeignKey(UsersTeams.USERS_TEAMS, DSL.name("USERS_TEAMS_USER_FK"), new TableField[] { UsersTeams.USERS_TEAMS.userId }, Keys.USER_PK, new TableField[] { User.USER.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); public static final ForeignKey VEX_PROJECT_FK = Internal.createForeignKey(Vex.VEX, DSL.name("VEX_PROJECT_FK"), new TableField[] { Vex.VEX.projectId }, Keys.PROJECT_PK, new TableField[] { Project.PROJECT.id }, true, ForeignKeyRule.CASCADE, ForeignKeyRule.NO_ACTION); diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java index 7ac47f6814..de08fda773 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Routines.java @@ -30,7 +30,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java index 6099c07b8d..3a75cfeb52 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/Tables.java @@ -58,8 +58,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.TeamsPermissions; import org.dependencytrack.persistence.jooq.generated.tables.User; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions; +import org.dependencytrack.persistence.jooq.generated.tables.UserProjectRoles; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions; -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams; import org.dependencytrack.persistence.jooq.generated.tables.Vex; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis; @@ -83,7 +83,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @@ -351,14 +351,14 @@ public class Tables { public static final UserProjectEffectivePermissions USER_PROJECT_EFFECTIVE_PERMISSIONS = UserProjectEffectivePermissions.USER_PROJECT_EFFECTIVE_PERMISSIONS; /** - * The table USERS_PERMISSIONS. + * The table USER_PROJECT_ROLES. */ - public static final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; + public static final UserProjectRoles USER_PROJECT_ROLES = UserProjectRoles.USER_PROJECT_ROLES; /** - * The table PROJECT_ROLE_BINDING. + * The table USERS_PERMISSIONS. */ - public static final ProjectRoleBinding PROJECT_ROLE_BINDING = ProjectRoleBinding.PROJECT_ROLE_BINDING; + public static final UsersPermissions USERS_PERMISSIONS = UsersPermissions.USERS_PERMISSIONS; /** * The table USERS_TEAMS. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java index 633b2102fe..4d5f209920 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/enums/Severity.java @@ -19,7 +19,7 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java index 8993cf3f17..c1fe920e0c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/CalcRiskScore.java @@ -24,14 +24,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class CalcRiskScore extends AbstractRoutine { - private static final long serialVersionUID = -2141815729; + private static final long serialVersionUID = 246055824; /** * The parameter CALC_RISK_SCORE.RETURN_VALUE. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java index 23e62fcde4..17ede8d193 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/HasProjectAccess.java @@ -22,14 +22,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class HasProjectAccess extends AbstractRoutine { - private static final long serialVersionUID = 1366074265; + private static final long serialVersionUID = -2056259366; /** * The parameter has_project_access.RETURN_VALUE. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java index e74a0899a3..c59f12320a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/JsonbVulnAliases.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class JsonbVulnAliases extends AbstractRoutine { - private static final long serialVersionUID = -1914958624; + private static final long serialVersionUID = -211077151; /** * The parameter jsonb_vuln_aliases.RETURN_VALUE. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java index 9d8a1c1f33..0041aacb3e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectEffectivePermissions.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RecalcUserProjectEffectivePermissions extends AbstractRoutine { - private static final long serialVersionUID = -2142402630; + private static final long serialVersionUID = 209537979; /** * The parameter diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java index 4f50b5d7d9..f891661119 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/RecalcUserProjectRoleEffectivePermissions.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RecalcUserProjectRoleEffectivePermissions extends AbstractRoutine { - private static final long serialVersionUID = 2073358932; + private static final long serialVersionUID = 981866517; /** * The parameter diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java index b761cba401..28ccd9ac54 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateComponentMetrics.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UpdateComponentMetrics extends AbstractRoutine { - private static final long serialVersionUID = -1702575277; + private static final long serialVersionUID = 693412594; /** * The parameter UPDATE_COMPONENT_METRICS.component_uuid. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java index bde55628d8..9dde900264 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdatePortfolioMetrics.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UpdatePortfolioMetrics extends AbstractRoutine { - private static final long serialVersionUID = 1444263983; + private static final long serialVersionUID = 362726158; /** * Create a new routine call instance diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java index 4a067a768d..2642dea513 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/routines/UpdateProjectMetrics.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UpdateProjectMetrics extends AbstractRoutine { - private static final long serialVersionUID = -612851025; + private static final long serialVersionUID = -337902706; /** * The parameter UPDATE_PROJECT_METRICS.project_uuid. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java index 1c12933d5c..1eeb7693ac 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AffectedVersionAttribution.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AffectedVersionAttribution extends TableImpl { - private static final long serialVersionUID = -938219356; + private static final long serialVersionUID = 1168662434; /** * The reference instance of AFFECTEDVERSIONATTRIBUTION @@ -146,13 +146,13 @@ public AffectedVersionAttribution(Table path, ForeignKey { - private static final long serialVersionUID = -938219356; + private static final long serialVersionUID = 1168662434; public AffectedVersionAttributionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java index 79cc5cd650..890d48fd65 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Analysis.java @@ -52,14 +52,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Analysis extends TableImpl { - private static final long serialVersionUID = -676941835; + private static final long serialVersionUID = 283558549; /** * The reference instance of ANALYSIS @@ -199,13 +199,13 @@ public Analysis(Table path, ForeignKey value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class AnalysisPath extends Analysis implements Path { - private static final long serialVersionUID = -676941835; + private static final long serialVersionUID = 283558549; public AnalysisPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java index e177fa9b31..2e941fa556 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/AnalysisComment.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AnalysisComment extends TableImpl { - private static final long serialVersionUID = 67920414; + private static final long serialVersionUID = -479012260; /** * The reference instance of ANALYSISCOMMENT @@ -134,13 +134,13 @@ public AnalysisComment(Table path, ForeignKey { - private static final long serialVersionUID = 67920414; + private static final long serialVersionUID = -479012260; public AnalysisCommentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java index 8b8de0594f..1da4f275f0 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKey.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKey extends TableImpl { - private static final long serialVersionUID = -711465365; + private static final long serialVersionUID = 1460309801; /** * The reference instance of APIKEY @@ -145,13 +145,13 @@ public ApiKey(Table path, ForeignKey chil value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class ApiKeyPath extends ApiKey implements Path { - private static final long serialVersionUID = -711465365; + private static final long serialVersionUID = 1460309801; public ApiKeyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java index 77c31c58e3..06da8c393b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ApiKeysTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKeysTeams extends TableImpl { - private static final long serialVersionUID = -1570762444; + private static final long serialVersionUID = -1464979308; /** * The reference instance of APIKEYS_TEAMS @@ -116,13 +116,13 @@ public ApiKeysTeams(Table path, ForeignKey { - private static final long serialVersionUID = -1570762444; + private static final long serialVersionUID = -1464979308; public ApiKeysTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java index 95b444ad30..4663dcacdb 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Bom.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Bom extends TableImpl { - private static final long serialVersionUID = -979504904; + private static final long serialVersionUID = -1177800744; /** * The reference instance of BOM @@ -155,13 +155,13 @@ public Bom(Table path, ForeignKey childPath, value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class BomPath extends Bom implements Path { - private static final long serialVersionUID = -979504904; + private static final long serialVersionUID = -1177800744; public BomPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java index f185bdb339..6f11ee23aa 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Component.java @@ -61,14 +61,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Component extends TableImpl { - private static final long serialVersionUID = -1731235713; + private static final long serialVersionUID = 950250689; /** * The reference instance of COMPONENT @@ -323,13 +323,13 @@ public Component(Table path, ForeignKey { - private static final long serialVersionUID = -1731235713; + private static final long serialVersionUID = 950250689; public ComponentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java index 1a6636480a..3f376b34ea 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentOccurrence.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentOccurrence extends TableImpl { - private static final long serialVersionUID = -1139580904; + private static final long serialVersionUID = 812694584; /** * The reference instance of COMPONENT_OCCURRENCE @@ -144,13 +144,13 @@ public ComponentOccurrence(Table path, ForeignKey { - private static final long serialVersionUID = -1139580904; + private static final long serialVersionUID = 812694584; public ComponentOccurrencePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java index 385e93e1c7..0c4cbec0b4 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentProperty.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentProperty extends TableImpl { - private static final long serialVersionUID = 2142097110; + private static final long serialVersionUID = -2102938216; /** * The reference instance of COMPONENT_PROPERTY @@ -151,13 +151,13 @@ public ComponentProperty(Table path, ForeignKey { - private static final long serialVersionUID = 2142097110; + private static final long serialVersionUID = -2102938216; public ComponentPropertyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java index 5b5b6e13ec..47c5551fac 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ComponentsVulnerabilities.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentsVulnerabilities extends TableImpl { - private static final long serialVersionUID = -2111707182; + private static final long serialVersionUID = -2031297584; /** * The reference instance of COMPONENTS_VULNERABILITIES @@ -117,13 +117,13 @@ public ComponentsVulnerabilities(Table path, ForeignKey { - private static final long serialVersionUID = -2111707182; + private static final long serialVersionUID = -2031297584; public ComponentsVulnerabilitiesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java index 865ddcbf2f..df15172d93 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ConfigProperty.java @@ -39,14 +39,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ConfigProperty extends TableImpl { - private static final long serialVersionUID = -1963189124; + private static final long serialVersionUID = 1282853723; /** * The reference instance of CONFIGPROPERTY diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java index 1e8cff1cdf..d9f4926e31 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/DependencyMetrics.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class DependencyMetrics extends TableImpl { - private static final long serialVersionUID = -589450869; + private static final long serialVersionUID = -876525619; /** * The reference instance of DEPENDENCYMETRICS @@ -265,13 +265,13 @@ public DependencyMetrics(Table path, ForeignKey { - private static final long serialVersionUID = -589450869; + private static final long serialVersionUID = -876525619; public DependencyMetricsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java index 126041a6c7..d81bd12fdb 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Epss.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Epss extends TableImpl { - private static final long serialVersionUID = 1806497615; + private static final long serialVersionUID = -1112588946; /** * The reference instance of EPSS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java index ad6073cd40..7278bb00b7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/FindingAttribution.java @@ -50,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class FindingAttribution extends TableImpl { - private static final long serialVersionUID = -1832451837; + private static final long serialVersionUID = -109488251; /** * The reference instance of FINDINGATTRIBUTION @@ -157,13 +157,13 @@ public FindingAttribution(Table path, ForeignKey { - private static final long serialVersionUID = -1832451837; + private static final long serialVersionUID = -109488251; public FindingAttributionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java index dfccb4a670..8ee08c8b96 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityAnalysis.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityAnalysis extends TableImpl { - private static final long serialVersionUID = -1888012935; + private static final long serialVersionUID = -1084259209; /** * The reference instance of INTEGRITY_ANALYSIS @@ -149,13 +149,13 @@ public IntegrityAnalysis(Table path, ForeignKey { - private static final long serialVersionUID = -1888012935; + private static final long serialVersionUID = -1084259209; public IntegrityAnalysisPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java index 84856f58c6..ce41b9607f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/IntegrityMetaComponent.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityMetaComponent extends TableImpl { - private static final long serialVersionUID = -1317194047; + private static final long serialVersionUID = 2122102304; /** * The reference instance of INTEGRITY_META_COMPONENT diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java index 011ae0778d..35dab58473 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/License.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class License extends TableImpl { - private static final long serialVersionUID = 660778313; + private static final long serialVersionUID = 1708455947; /** * The reference instance of LICENSE @@ -175,13 +175,13 @@ public License(Table path, ForeignKey ch value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class LicensePath extends License implements Path { - private static final long serialVersionUID = 660778313; + private static final long serialVersionUID = 1708455947; public LicensePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java index ffcbe3ab51..0a839cf6ac 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroup.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroup extends TableImpl { - private static final long serialVersionUID = 1648671036; + private static final long serialVersionUID = 1916655004; /** * The reference instance of LICENSEGROUP @@ -129,13 +129,13 @@ public LicenseGroup(Table path, ForeignKey { - private static final long serialVersionUID = 1648671036; + private static final long serialVersionUID = 1916655004; public LicenseGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java index fb731ddec5..f6a6ae0d0b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/LicenseGroupLicense.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroupLicense extends TableImpl { - private static final long serialVersionUID = 224650408; + private static final long serialVersionUID = 699105800; /** * The reference instance of LICENSEGROUP_LICENSE @@ -117,13 +117,13 @@ public LicenseGroupLicense(Table path, ForeignKey { - private static final long serialVersionUID = 224650408; + private static final long serialVersionUID = 699105800; public LicenseGroupLicensePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java index 0ff959fd1c..5537aca3f8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedLdapGroup.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedLdapGroup extends TableImpl { - private static final long serialVersionUID = 1776230963; + private static final long serialVersionUID = -852102219; /** * The reference instance of MAPPEDLDAPGROUP @@ -126,13 +126,13 @@ public MappedLdapGroup(Table path, ForeignKey { - private static final long serialVersionUID = 1776230963; + private static final long serialVersionUID = -852102219; public MappedLdapGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java index d46720a004..e85ecd66ac 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/MappedOidcGroup.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedOidcGroup extends TableImpl { - private static final long serialVersionUID = 610435687; + private static final long serialVersionUID = 538043813; /** * The reference instance of MAPPEDOIDCGROUP @@ -129,13 +129,13 @@ public MappedOidcGroup(Table path, ForeignKey { - private static final long serialVersionUID = 610435687; + private static final long serialVersionUID = 538043813; public MappedOidcGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java index d4ea29e6eb..065645101a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationPublisher.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationPublisher extends TableImpl { - private static final long serialVersionUID = -1076695095; + private static final long serialVersionUID = 1114137099; /** * The reference instance of NOTIFICATIONPUBLISHER @@ -147,13 +147,13 @@ public NotificationPublisher(Table path, ForeignKey { - private static final long serialVersionUID = -1076695095; + private static final long serialVersionUID = 1114137099; public NotificationPublisherPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java index 9c0bae12af..91e52d0dd9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRule.java @@ -52,14 +52,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRule extends TableImpl { - private static final long serialVersionUID = 1113696852; + private static final long serialVersionUID = -1237866188; /** * The reference instance of NOTIFICATIONRULE @@ -174,13 +174,13 @@ public NotificationRule(Table path, ForeignKey { - private static final long serialVersionUID = 1113696852; + private static final long serialVersionUID = -1237866188; public NotificationRulePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java index 2eaf3bd7f3..30e5a82f34 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleProjects.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleProjects extends TableImpl { - private static final long serialVersionUID = 810213248; + private static final long serialVersionUID = 1487178754; /** * The reference instance of NOTIFICATIONRULE_PROJECTS @@ -117,13 +117,13 @@ public NotificationRuleProjects(Table path, ForeignKey { - private static final long serialVersionUID = 810213248; + private static final long serialVersionUID = 1487178754; public NotificationRuleProjectsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java index 2209a6d143..4644867d84 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTags extends TableImpl { - private static final long serialVersionUID = 1998603530; + private static final long serialVersionUID = 2086958220; /** * The reference instance of NOTIFICATIONRULE_TAGS @@ -116,13 +116,13 @@ public NotificationRuleTags(Table path, ForeignKey { - private static final long serialVersionUID = 1998603530; + private static final long serialVersionUID = 2086958220; public NotificationRuleTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java index ff730d97df..4a6dfbb012 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/NotificationRuleTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTeams extends TableImpl { - private static final long serialVersionUID = 802684418; + private static final long serialVersionUID = -727005120; /** * The reference instance of NOTIFICATIONRULE_TEAMS @@ -116,13 +116,13 @@ public NotificationRuleTeams(Table path, ForeignKey { - private static final long serialVersionUID = 802684418; + private static final long serialVersionUID = -727005120; public NotificationRuleTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java index 23e91a6b06..b39479aeb5 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/OidcGroup.java @@ -46,14 +46,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class OidcGroup extends TableImpl { - private static final long serialVersionUID = -561573330; + private static final long serialVersionUID = -1429900146; /** * The reference instance of OIDCGROUP @@ -123,13 +123,13 @@ public OidcGroup(Table path, ForeignKey { - private static final long serialVersionUID = -561573330; + private static final long serialVersionUID = -1429900146; public OidcGroupPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java index 35345c8419..46821e6c69 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Permission.java @@ -50,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Permission extends TableImpl { - private static final long serialVersionUID = 1134556928; + private static final long serialVersionUID = 1887509984; /** * The reference instance of PERMISSION @@ -127,13 +127,13 @@ public Permission(Table path, ForeignKey { - private static final long serialVersionUID = 1134556928; + private static final long serialVersionUID = 1887509984; public PermissionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java index 03cacc345f..40f20de7bb 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Policy.java @@ -50,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Policy extends TableImpl { - private static final long serialVersionUID = -763533389; + private static final long serialVersionUID = -1941017999; /** * The reference instance of POLICY @@ -147,13 +147,13 @@ public Policy(Table path, ForeignKey chil value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class PolicyPath extends Policy implements Path { - private static final long serialVersionUID = -763533389; + private static final long serialVersionUID = -1941017999; public PolicyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java index 0419247592..62418ff076 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyCondition.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyCondition extends TableImpl { - private static final long serialVersionUID = -765297543; + private static final long serialVersionUID = 1066216251; /** * The reference instance of POLICYCONDITION @@ -145,13 +145,13 @@ public PolicyCondition(Table path, ForeignKey { - private static final long serialVersionUID = -765297543; + private static final long serialVersionUID = 1066216251; public PolicyConditionPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java index ee93f6bbcf..f5e0a57f7d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyProjects.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyProjects extends TableImpl { - private static final long serialVersionUID = -599792149; + private static final long serialVersionUID = 482510445; /** * The reference instance of POLICY_PROJECTS @@ -117,13 +117,13 @@ public PolicyProjects(Table path, ForeignKey { - private static final long serialVersionUID = -599792149; + private static final long serialVersionUID = 482510445; public PolicyProjectsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java index f4336355ee..2700106ee6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyTags extends TableImpl { - private static final long serialVersionUID = -971385270; + private static final long serialVersionUID = 90177356; /** * The reference instance of POLICY_TAGS @@ -116,13 +116,13 @@ public PolicyTags(Table path, ForeignKey { - private static final long serialVersionUID = -971385270; + private static final long serialVersionUID = 90177356; public PolicyTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java index 7e9758d98d..bc09a0714c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PolicyViolation.java @@ -51,14 +51,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyViolation extends TableImpl { - private static final long serialVersionUID = 1684309677; + private static final long serialVersionUID = 1829081903; /** * The reference instance of POLICYVIOLATION @@ -153,13 +153,13 @@ public PolicyViolation(Table path, ForeignKey { - private static final long serialVersionUID = 1684309677; + private static final long serialVersionUID = 1829081903; public PolicyViolationPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java index 9a0df136e8..fdfa3670b4 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/PortfolioMetrics.java @@ -37,14 +37,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PortfolioMetrics extends TableImpl { - private static final long serialVersionUID = 1604183279; + private static final long serialVersionUID = 1191794800; /** * The reference instance of PORTFOLIOMETRICS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java index 4c8546b71a..81818ef80d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Project.java @@ -34,7 +34,7 @@ import org.dependencytrack.persistence.jooq.generated.tables.Tag.TagPath; import org.dependencytrack.persistence.jooq.generated.tables.Team.TeamPath; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions.UserProjectEffectivePermissionsPath; -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding.UsersProjectsRolesPath; +import org.dependencytrack.persistence.jooq.generated.tables.UserProjectRoles.UserProjectRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.Vex.VexPath; import org.dependencytrack.persistence.jooq.generated.tables.ViolationAnalysis.ViolationAnalysisPath; import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectRecord; @@ -72,14 +72,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Project extends TableImpl { - private static final long serialVersionUID = -1297445188; + private static final long serialVersionUID = -1788679128; /** * The reference instance of PROJECT @@ -244,13 +244,13 @@ public Project(Table path, ForeignKey ch value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class ProjectPath extends Project implements Path { - private static final long serialVersionUID = -1297445188; + private static final long serialVersionUID = -1788679128; public ProjectPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } @@ -534,17 +534,17 @@ public UserProjectEffectivePermissionsPath userProjectEffectivePermissions() { return _userProjectEffectivePermissions; } - private transient UsersProjectsRolesPath _usersProjectsRoles; + private transient UserProjectRolesPath _userProjectRoles; /** - * Get the implicit to-many join path to the - * PROJECT_ROLE_BINDING table + * Get the implicit to-many join path to the USER_PROJECT_ROLES + * table */ - public UsersProjectsRolesPath usersProjectsRoles() { - if (_usersProjectsRoles == null) - _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.PROJECT_ROLE_BINDING_PROJECT_FK.getInverseKey()); + public UserProjectRolesPath userProjectRoles() { + if (_userProjectRoles == null) + _userProjectRoles = new UserProjectRolesPath(this, null, Keys.USER_PROJECT_ROLES_PROJECT_FK.getInverseKey()); - return _usersProjectsRoles; + return _userProjectRoles; } private transient VexPath _vex; diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java index 009718437f..ca371817f9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectAccessTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectAccessTeams extends TableImpl { - private static final long serialVersionUID = 873948858; + private static final long serialVersionUID = 308377242; /** * The reference instance of PROJECT_ACCESS_TEAMS @@ -116,13 +116,13 @@ public ProjectAccessTeams(Table path, ForeignKey { - private static final long serialVersionUID = 873948858; + private static final long serialVersionUID = 308377242; public ProjectAccessTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java index 3f2cfd54ec..72efbfad8a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectHierarchy.java @@ -43,14 +43,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectHierarchy extends TableImpl { - private static final long serialVersionUID = 75786160; + private static final long serialVersionUID = -421841490; /** * The reference instance of PROJECT_HIERARCHY @@ -120,13 +120,13 @@ public ProjectHierarchy(Table path, ForeignKey { - private static final long serialVersionUID = 75786160; + private static final long serialVersionUID = -421841490; public ProjectHierarchyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java index 359b8b5a47..6ead589780 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetadata.java @@ -46,14 +46,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetadata extends TableImpl { - private static final long serialVersionUID = 228933682; + private static final long serialVersionUID = -599705872; /** * The reference instance of PROJECT_METADATA @@ -133,13 +133,13 @@ public ProjectMetadata(Table path, ForeignKey { - private static final long serialVersionUID = 228933682; + private static final long serialVersionUID = -599705872; public ProjectMetadataPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java index 12477b9928..89c741e0a8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectMetrics.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetrics extends TableImpl { - private static final long serialVersionUID = -1382780670; + private static final long serialVersionUID = -946369084; /** * The reference instance of PROJECTMETRICS @@ -266,13 +266,13 @@ public ProjectMetrics(Table path, ForeignKey { - private static final long serialVersionUID = -1382780670; + private static final long serialVersionUID = -946369084; public ProjectMetricsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java index c5b1e9ea29..8825b278fd 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectProperty.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectProperty extends TableImpl { - private static final long serialVersionUID = 44418381; + private static final long serialVersionUID = 2042495951; /** * The reference instance of PROJECT_PROPERTY @@ -141,13 +141,13 @@ public ProjectProperty(Table path, ForeignKey { - private static final long serialVersionUID = 44418381; + private static final long serialVersionUID = 2042495951; public ProjectPropertyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectRoleBinding.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectRoleBinding.java deleted file mode 100644 index 0d24f58833..0000000000 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectRoleBinding.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * This file is generated by jOOQ. - */ -package org.dependencytrack.persistence.jooq.generated.tables; - - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import javax.annotation.processing.Generated; - -import org.dependencytrack.persistence.jooq.generated.DefaultSchema; -import org.dependencytrack.persistence.jooq.generated.Indexes; -import org.dependencytrack.persistence.jooq.generated.Keys; -import org.dependencytrack.persistence.jooq.generated.tables.Project.ProjectPath; -import org.dependencytrack.persistence.jooq.generated.tables.Role.RolePath; -import org.dependencytrack.persistence.jooq.generated.tables.User.UserPath; -import org.dependencytrack.persistence.jooq.generated.tables.records.ProjectRoleBindingRecord; -import org.jooq.Condition; -import org.jooq.Field; -import org.jooq.ForeignKey; -import org.jooq.Index; -import org.jooq.InverseForeignKey; -import org.jooq.Name; -import org.jooq.Path; -import org.jooq.PlainSQL; -import org.jooq.QueryPart; -import org.jooq.Record; -import org.jooq.SQL; -import org.jooq.Schema; -import org.jooq.Select; -import org.jooq.Stringly; -import org.jooq.Table; -import org.jooq.TableField; -import org.jooq.TableOptions; -import org.jooq.impl.DSL; -import org.jooq.impl.SQLDataType; -import org.jooq.impl.TableImpl; - - -/** - * This class is generated by jOOQ. - */ -@Generated( - value = { - "https://www.jooq.org", - "jOOQ version:3.20.4", - "schema version:v5.6.0-27" - }, - comments = "This class is generated by jOOQ" -) -@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) -public class ProjectRoleBinding extends TableImpl { - - private static final long serialVersionUID = 622585294; - - /** - * The reference instance of PROJECT_ROLE_BINDING - */ - public static final ProjectRoleBinding PROJECT_ROLE_BINDING = new ProjectRoleBinding(); - - /** - * The class holding records for this type - */ - @Override - public Class getRecordType() { - return ProjectRoleBindingRecord.class; - } - - /** - * The column PROJECT_ROLE_BINDING.USER_ID. - */ - public final TableField userId = createField(DSL.name("USER_ID"), SQLDataType.BIGINT.nullable(false), this, ""); - - /** - * The column PROJECT_ROLE_BINDING.PROJECT_ID. - */ - public final TableField projectId = createField(DSL.name("PROJECT_ID"), SQLDataType.BIGINT.nullable(false), this, ""); - - /** - * The column PROJECT_ROLE_BINDING.ROLE_ID. - */ - public final TableField roleId = createField(DSL.name("ROLE_ID"), SQLDataType.BIGINT.nullable(false), this, ""); - - private ProjectRoleBinding(Name alias, Table aliased) { - this(alias, aliased, (Field[]) null, null); - } - - private ProjectRoleBinding(Name alias, Table aliased, Field[] parameters, Condition where) { - super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); - } - - /** - * Create an aliased PROJECT_ROLE_BINDING table reference - */ - public ProjectRoleBinding(String alias) { - this(DSL.name(alias), PROJECT_ROLE_BINDING); - } - - /** - * Create an aliased PROJECT_ROLE_BINDING table reference - */ - public ProjectRoleBinding(Name alias) { - this(alias, PROJECT_ROLE_BINDING); - } - - /** - * Create a PROJECT_ROLE_BINDING table reference - */ - public ProjectRoleBinding() { - this(DSL.name("PROJECT_ROLE_BINDING"), null); - } - - public ProjectRoleBinding(Table path, ForeignKey childPath, InverseForeignKey parentPath) { - super(path, childPath, parentPath, PROJECT_ROLE_BINDING); - } - - /** - * A subtype implementing {@link Path} for simplified path-based joins. - */ - @Generated( - value = { - "https://www.jooq.org", - "jOOQ version:3.20.4", - "schema version:v5.6.0-27" - }, - comments = "This class is generated by jOOQ" - ) - public static class UsersProjectsRolesPath extends ProjectRoleBinding implements Path { - - private static final long serialVersionUID = 622585294; - public UsersProjectsRolesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { - super(path, childPath, parentPath); - } - private UsersProjectsRolesPath(Name alias, Table aliased) { - super(alias, aliased); - } - - @Override - public UsersProjectsRolesPath as(String alias) { - return new UsersProjectsRolesPath(DSL.name(alias), this); - } - - @Override - public UsersProjectsRolesPath as(Name alias) { - return new UsersProjectsRolesPath(alias, this); - } - - @Override - public UsersProjectsRolesPath as(Table alias) { - return new UsersProjectsRolesPath(alias.getQualifiedName(), this); - } - } - - @Override - public Schema getSchema() { - return aliased() ? null : DefaultSchema.DEFAULT_SCHEMA; - } - - @Override - public List getIndexes() { - return Arrays.asList(Indexes.PROJECT_ROLE_BINDING_ROLE_ID_IDX, Indexes.PROJECT_ROLE_BINDING_USER_PROJECT_IDX); - } - - @Override - public List> getReferences() { - return Arrays.asList(Keys.PROJECT_ROLE_BINDING_PROJECT_FK, Keys.PROJECT_ROLE_BINDING_ROLE_FK, Keys.PROJECT_ROLE_BINDING_USER_FK); - } - - private transient ProjectPath _project; - - /** - * Get the implicit join path to the PROJECT table. - */ - public ProjectPath project() { - if (_project == null) - _project = new ProjectPath(this, Keys.PROJECT_ROLE_BINDING_PROJECT_FK, null); - - return _project; - } - - private transient RolePath _role; - - /** - * Get the implicit join path to the ROLE table. - */ - public RolePath role() { - if (_role == null) - _role = new RolePath(this, Keys.PROJECT_ROLE_BINDING_ROLE_FK, null); - - return _role; - } - - private transient UserPath _user; - - /** - * Get the implicit join path to the USER table. - */ - public UserPath user() { - if (_user == null) - _user = new UserPath(this, Keys.PROJECT_ROLE_BINDING_USER_FK, null); - - return _user; - } - - @Override - public ProjectRoleBinding as(String alias) { - return new ProjectRoleBinding(DSL.name(alias), this); - } - - @Override - public ProjectRoleBinding as(Name alias) { - return new ProjectRoleBinding(alias, this); - } - - @Override - public ProjectRoleBinding as(Table alias) { - return new ProjectRoleBinding(alias.getQualifiedName(), this); - } - - /** - * Rename this table - */ - @Override - public ProjectRoleBinding rename(String name) { - return new ProjectRoleBinding(DSL.name(name), null); - } - - /** - * Rename this table - */ - @Override - public ProjectRoleBinding rename(Name name) { - return new ProjectRoleBinding(name, null); - } - - /** - * Rename this table - */ - @Override - public ProjectRoleBinding rename(Table name) { - return new ProjectRoleBinding(name.getQualifiedName(), null); - } - - /** - * Create an inline derived table from this table - */ - @Override - public ProjectRoleBinding where(Condition condition) { - return new ProjectRoleBinding(getQualifiedName(), aliased() ? this : null, null, condition); - } - - /** - * Create an inline derived table from this table - */ - @Override - public ProjectRoleBinding where(Collection conditions) { - return where(DSL.and(conditions)); - } - - /** - * Create an inline derived table from this table - */ - @Override - public ProjectRoleBinding where(Condition... conditions) { - return where(DSL.and(conditions)); - } - - /** - * Create an inline derived table from this table - */ - @Override - public ProjectRoleBinding where(Field condition) { - return where(DSL.condition(condition)); - } - - /** - * Create an inline derived table from this table - */ - @Override - @PlainSQL - public ProjectRoleBinding where(SQL condition) { - return where(DSL.condition(condition)); - } - - /** - * Create an inline derived table from this table - */ - @Override - @PlainSQL - public ProjectRoleBinding where(@Stringly.SQL String condition) { - return where(DSL.condition(condition)); - } - - /** - * Create an inline derived table from this table - */ - @Override - @PlainSQL - public ProjectRoleBinding where(@Stringly.SQL String condition, Object... binds) { - return where(DSL.condition(condition, binds)); - } - - /** - * Create an inline derived table from this table - */ - @Override - @PlainSQL - public ProjectRoleBinding where(@Stringly.SQL String condition, QueryPart... parts) { - return where(DSL.condition(condition, parts)); - } - - /** - * Create an inline derived table from this table - */ - @Override - public ProjectRoleBinding whereExists(Select select) { - return where(DSL.exists(select)); - } - - /** - * Create an inline derived table from this table - */ - @Override - public ProjectRoleBinding whereNotExists(Select select) { - return where(DSL.notExists(select)); - } -} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java index 346fb62f47..28af923b47 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ProjectsTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectsTags extends TableImpl { - private static final long serialVersionUID = -163939250; + private static final long serialVersionUID = -58156114; /** * The reference instance of PROJECTS_TAGS @@ -116,13 +116,13 @@ public ProjectsTags(Table path, ForeignKey { - private static final long serialVersionUID = -163939250; + private static final long serialVersionUID = -58156114; public ProjectsTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java index 7ddf8ff687..864df9c936 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Repository.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Repository extends TableImpl { - private static final long serialVersionUID = 1139153193; + private static final long serialVersionUID = -1708907256; /** * The reference instance of REPOSITORY diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java index c370ea530d..9c18403541 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RepositoryMetaComponent.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RepositoryMetaComponent extends TableImpl { - private static final long serialVersionUID = 1187611547; + private static final long serialVersionUID = -1352376868; /** * The reference instance of REPOSITORY_META_COMPONENT diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java index fbd3f4dd97..0e39043e55 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Role.java @@ -15,7 +15,7 @@ import org.dependencytrack.persistence.jooq.generated.Keys; import org.dependencytrack.persistence.jooq.generated.tables.Permission.PermissionPath; import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions.RolesPermissionsPath; -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding.UsersProjectsRolesPath; +import org.dependencytrack.persistence.jooq.generated.tables.UserProjectRoles.UserProjectRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.records.RoleRecord; import org.jooq.Condition; import org.jooq.Field; @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Role extends TableImpl { - private static final long serialVersionUID = -1832423169; + private static final long serialVersionUID = -30181175; /** * The reference instance of ROLE @@ -124,13 +124,13 @@ public Role(Table path, ForeignKey childPat value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class RolePath extends Role implements Path { - private static final long serialVersionUID = -1832423169; + private static final long serialVersionUID = -30181175; public RolePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } @@ -187,17 +187,17 @@ public RolesPermissionsPath rolesPermissions() { return _rolesPermissions; } - private transient UsersProjectsRolesPath _usersProjectsRoles; + private transient UserProjectRolesPath _userProjectRoles; /** - * Get the implicit to-many join path to the - * PROJECT_ROLE_BINDING table + * Get the implicit to-many join path to the USER_PROJECT_ROLES + * table */ - public UsersProjectsRolesPath usersProjectsRoles() { - if (_usersProjectsRoles == null) - _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.PROJECT_ROLE_BINDING_ROLE_FK.getInverseKey()); + public UserProjectRolesPath userProjectRoles() { + if (_userProjectRoles == null) + _userProjectRoles = new UserProjectRolesPath(this, null, Keys.USER_PROJECT_ROLES_ROLE_FK.getInverseKey()); - return _usersProjectsRoles; + return _userProjectRoles; } /** diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java index e783f8437e..73caad62fe 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/RolesPermissions.java @@ -11,7 +11,6 @@ import javax.annotation.processing.Generated; import org.dependencytrack.persistence.jooq.generated.DefaultSchema; -import org.dependencytrack.persistence.jooq.generated.Indexes; import org.dependencytrack.persistence.jooq.generated.Keys; import org.dependencytrack.persistence.jooq.generated.tables.Permission.PermissionPath; import org.dependencytrack.persistence.jooq.generated.tables.Role.RolePath; @@ -19,7 +18,6 @@ import org.jooq.Condition; import org.jooq.Field; import org.jooq.ForeignKey; -import org.jooq.Index; import org.jooq.InverseForeignKey; import org.jooq.Name; import org.jooq.Path; @@ -46,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RolesPermissions extends TableImpl { - private static final long serialVersionUID = 188042180; + private static final long serialVersionUID = -1187218808; /** * The reference instance of ROLES_PERMISSIONS @@ -118,13 +116,13 @@ public RolesPermissions(Table path, ForeignKey { - private static final long serialVersionUID = 188042180; + private static final long serialVersionUID = -1187218808; public RolesPermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } @@ -154,13 +152,8 @@ public Schema getSchema() { } @Override - public List getIndexes() { - return Arrays.asList(Indexes.ROLES_PERMISSIONS_PERMISSION_ID_IDX, Indexes.ROLES_PERMISSIONS_ROLE_ID_IDX); - } - - @Override - public List> getUniqueKeys() { - return Arrays.asList(Keys.ROLES_PERMISSIONS_COMPOSITE_IDX); + public UniqueKey getPrimaryKey() { + return Keys.ROLES_PERMISSIONS_PK; } @Override diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java index c5628dfa8d..c80246e7da 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponent.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponent extends TableImpl { - private static final long serialVersionUID = -1366507819; + private static final long serialVersionUID = 203170229; /** * The reference instance of SERVICECOMPONENT @@ -191,13 +191,13 @@ public ServiceComponent(Table path, ForeignKey { - private static final long serialVersionUID = -1366507819; + private static final long serialVersionUID = 203170229; public ServiceComponentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java index daa582f4e6..47ce162f41 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ServiceComponentsVulnerabilities.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponentsVulnerabilities extends TableImpl { - private static final long serialVersionUID = -991095685; + private static final long serialVersionUID = -45138371; /** * The reference instance of SERVICECOMPONENTS_VULNERABILITIES @@ -121,13 +121,13 @@ public ServiceComponentsVulnerabilities(Table path, Foreig value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class ServiceComponentsVulnerabilitiesPath extends ServiceComponentsVulnerabilities implements Path { - private static final long serialVersionUID = -991095685; + private static final long serialVersionUID = -45138371; public ServiceComponentsVulnerabilitiesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java index a57b60bee6..c820ae49db 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Tag.java @@ -52,14 +52,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Tag extends TableImpl { - private static final long serialVersionUID = -59691910; + private static final long serialVersionUID = 368852536; /** * The reference instance of TAG @@ -124,13 +124,13 @@ public Tag(Table path, ForeignKey childPath, value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class TagPath extends Tag implements Path { - private static final long serialVersionUID = -59691910; + private static final long serialVersionUID = 368852536; public TagPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java index b73798a4f6..91135427d6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Team.java @@ -53,14 +53,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Team extends TableImpl { - private static final long serialVersionUID = 638132231; + private static final long serialVersionUID = -183282137; /** * The reference instance of TEAM @@ -130,13 +130,13 @@ public Team(Table path, ForeignKey childPat value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class TeamPath extends Team implements Path { - private static final long serialVersionUID = 638132231; + private static final long serialVersionUID = -183282137; public TeamPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java index 10df9304d3..450e8d1683 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/TeamsPermissions.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TeamsPermissions extends TableImpl { - private static final long serialVersionUID = -1593956964; + private static final long serialVersionUID = -230464260; /** * The reference instance of TEAMS_PERMISSIONS @@ -116,13 +116,13 @@ public TeamsPermissions(Table path, ForeignKey { - private static final long serialVersionUID = -1593956964; + private static final long serialVersionUID = -230464260; public TeamsPermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java index bddbb87ed0..ce459e3825 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/User.java @@ -17,8 +17,8 @@ import org.dependencytrack.persistence.jooq.generated.tables.Permission.PermissionPath; import org.dependencytrack.persistence.jooq.generated.tables.Team.TeamPath; import org.dependencytrack.persistence.jooq.generated.tables.UserProjectEffectivePermissions.UserProjectEffectivePermissionsPath; +import org.dependencytrack.persistence.jooq.generated.tables.UserProjectRoles.UserProjectRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.UsersPermissions.UsersPermissionsPath; -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding.UsersProjectsRolesPath; import org.dependencytrack.persistence.jooq.generated.tables.UsersTeams.UsersTeamsPath; import org.dependencytrack.persistence.jooq.generated.tables.records.UserRecord; import org.jooq.Check; @@ -54,14 +54,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class User extends TableImpl { - private static final long serialVersionUID = -712068352; + private static final long serialVersionUID = -1214186122; /** * The reference instance of USER @@ -176,13 +176,13 @@ public User(Table path, ForeignKey childPat value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class UserPath extends User implements Path { - private static final long serialVersionUID = -712068352; + private static final long serialVersionUID = -1214186122; public UserPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } @@ -239,30 +239,30 @@ public UserProjectEffectivePermissionsPath userProjectEffectivePermissions() { return _userProjectEffectivePermissions; } - private transient UsersPermissionsPath _usersPermissions; + private transient UserProjectRolesPath _userProjectRoles; /** - * Get the implicit to-many join path to the USERS_PERMISSIONS + * Get the implicit to-many join path to the USER_PROJECT_ROLES * table */ - public UsersPermissionsPath usersPermissions() { - if (_usersPermissions == null) - _usersPermissions = new UsersPermissionsPath(this, null, Keys.USERS_PERMISSIONS_USER_FK.getInverseKey()); + public UserProjectRolesPath userProjectRoles() { + if (_userProjectRoles == null) + _userProjectRoles = new UserProjectRolesPath(this, null, Keys.USER_PROJECT_ROLES_USER_FK.getInverseKey()); - return _usersPermissions; + return _userProjectRoles; } - private transient UsersProjectsRolesPath _usersProjectsRoles; + private transient UsersPermissionsPath _usersPermissions; /** - * Get the implicit to-many join path to the - * PROJECT_ROLE_BINDING table + * Get the implicit to-many join path to the USERS_PERMISSIONS + * table */ - public UsersProjectsRolesPath usersProjectsRoles() { - if (_usersProjectsRoles == null) - _usersProjectsRoles = new UsersProjectsRolesPath(this, null, Keys.PROJECT_ROLE_BINDING_USER_FK.getInverseKey()); + public UsersPermissionsPath usersPermissions() { + if (_usersPermissions == null) + _usersPermissions = new UsersPermissionsPath(this, null, Keys.USERS_PERMISSIONS_USER_FK.getInverseKey()); - return _usersProjectsRoles; + return _usersPermissions; } private transient UsersTeamsPath _usersTeams; diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java index 4a45ced47d..338c97897e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectEffectivePermissions.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UserProjectEffectivePermissions extends TableImpl { - private static final long serialVersionUID = 2035432985; + private static final long serialVersionUID = 166918427; /** * The reference instance of USER_PROJECT_EFFECTIVE_PERMISSIONS @@ -130,13 +130,13 @@ public UserProjectEffectivePermissions(Table path, Foreign value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class UserProjectEffectivePermissionsPath extends UserProjectEffectivePermissions implements Path { - private static final long serialVersionUID = 2035432985; + private static final long serialVersionUID = 166918427; public UserProjectEffectivePermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectRoles.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectRoles.java new file mode 100644 index 0000000000..95e44ed801 --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UserProjectRoles.java @@ -0,0 +1,328 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables; + + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.DefaultSchema; +import org.dependencytrack.persistence.jooq.generated.Keys; +import org.dependencytrack.persistence.jooq.generated.tables.Project.ProjectPath; +import org.dependencytrack.persistence.jooq.generated.tables.Role.RolePath; +import org.dependencytrack.persistence.jooq.generated.tables.User.UserPath; +import org.dependencytrack.persistence.jooq.generated.tables.records.UserProjectRolesRecord; +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.InverseForeignKey; +import org.jooq.Name; +import org.jooq.Path; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.Record; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-28" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class UserProjectRoles extends TableImpl { + + private static final long serialVersionUID = 1709797821; + + /** + * The reference instance of USER_PROJECT_ROLES + */ + public static final UserProjectRoles USER_PROJECT_ROLES = new UserProjectRoles(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return UserProjectRolesRecord.class; + } + + /** + * The column USER_PROJECT_ROLES.USER_ID. + */ + public final TableField userId = createField(DSL.name("USER_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + /** + * The column USER_PROJECT_ROLES.PROJECT_ID. + */ + public final TableField projectId = createField(DSL.name("PROJECT_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + /** + * The column USER_PROJECT_ROLES.ROLE_ID. + */ + public final TableField roleId = createField(DSL.name("ROLE_ID"), SQLDataType.BIGINT.nullable(false), this, ""); + + private UserProjectRoles(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private UserProjectRoles(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased USER_PROJECT_ROLES table reference + */ + public UserProjectRoles(String alias) { + this(DSL.name(alias), USER_PROJECT_ROLES); + } + + /** + * Create an aliased USER_PROJECT_ROLES table reference + */ + public UserProjectRoles(Name alias) { + this(alias, USER_PROJECT_ROLES); + } + + /** + * Create a USER_PROJECT_ROLES table reference + */ + public UserProjectRoles() { + this(DSL.name("USER_PROJECT_ROLES"), null); + } + + public UserProjectRoles(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath, USER_PROJECT_ROLES); + } + + /** + * A subtype implementing {@link Path} for simplified path-based joins. + */ + @Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-28" + }, + comments = "This class is generated by jOOQ" + ) + public static class UserProjectRolesPath extends UserProjectRoles implements Path { + + private static final long serialVersionUID = 1709797821; + public UserProjectRolesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + super(path, childPath, parentPath); + } + private UserProjectRolesPath(Name alias, Table aliased) { + super(alias, aliased); + } + + @Override + public UserProjectRolesPath as(String alias) { + return new UserProjectRolesPath(DSL.name(alias), this); + } + + @Override + public UserProjectRolesPath as(Name alias) { + return new UserProjectRolesPath(alias, this); + } + + @Override + public UserProjectRolesPath as(Table alias) { + return new UserProjectRolesPath(alias.getQualifiedName(), this); + } + } + + @Override + public Schema getSchema() { + return aliased() ? null : DefaultSchema.DEFAULT_SCHEMA; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.USER_PROJECT_ROLES_PK; + } + + @Override + public List> getReferences() { + return Arrays.asList(Keys.USER_PROJECT_ROLES_PROJECT_FK, Keys.USER_PROJECT_ROLES_ROLE_FK, Keys.USER_PROJECT_ROLES_USER_FK); + } + + private transient ProjectPath _project; + + /** + * Get the implicit join path to the PROJECT table. + */ + public ProjectPath project() { + if (_project == null) + _project = new ProjectPath(this, Keys.USER_PROJECT_ROLES_PROJECT_FK, null); + + return _project; + } + + private transient RolePath _role; + + /** + * Get the implicit join path to the ROLE table. + */ + public RolePath role() { + if (_role == null) + _role = new RolePath(this, Keys.USER_PROJECT_ROLES_ROLE_FK, null); + + return _role; + } + + private transient UserPath _user; + + /** + * Get the implicit join path to the USER table. + */ + public UserPath user() { + if (_user == null) + _user = new UserPath(this, Keys.USER_PROJECT_ROLES_USER_FK, null); + + return _user; + } + + @Override + public UserProjectRoles as(String alias) { + return new UserProjectRoles(DSL.name(alias), this); + } + + @Override + public UserProjectRoles as(Name alias) { + return new UserProjectRoles(alias, this); + } + + @Override + public UserProjectRoles as(Table alias) { + return new UserProjectRoles(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public UserProjectRoles rename(String name) { + return new UserProjectRoles(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public UserProjectRoles rename(Name name) { + return new UserProjectRoles(name, null); + } + + /** + * Rename this table + */ + @Override + public UserProjectRoles rename(Table name) { + return new UserProjectRoles(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UserProjectRoles where(Condition condition) { + return new UserProjectRoles(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UserProjectRoles where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UserProjectRoles where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UserProjectRoles where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UserProjectRoles where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UserProjectRoles where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UserProjectRoles where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public UserProjectRoles where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UserProjectRoles whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public UserProjectRoles whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java index da021e3340..6e838b30e1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersPermissions.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersPermissions extends TableImpl { - private static final long serialVersionUID = -1206928892; + private static final long serialVersionUID = 156563812; /** * The reference instance of USERS_PERMISSIONS @@ -116,13 +116,13 @@ public UsersPermissions(Table path, ForeignKey { - private static final long serialVersionUID = -1206928892; + private static final long serialVersionUID = 156563812; public UsersPermissionsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java index 06ebbc541f..5607d7efe6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/UsersTeams.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersTeams extends TableImpl { - private static final long serialVersionUID = 274318204; + private static final long serialVersionUID = -118009124; /** * The reference instance of USERS_TEAMS @@ -116,13 +116,13 @@ public UsersTeams(Table path, ForeignKey { - private static final long serialVersionUID = 274318204; + private static final long serialVersionUID = -118009124; public UsersTeamsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java index df860ea400..dfc5f98678 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vex.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Vex extends TableImpl { - private static final long serialVersionUID = -865420210; + private static final long serialVersionUID = 580983278; /** * The reference instance of VEX @@ -150,13 +150,13 @@ public Vex(Table path, ForeignKey childPath, value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class VexPath extends Vex implements Path { - private static final long serialVersionUID = -865420210; + private static final long serialVersionUID = 580983278; public VexPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java index 94a9914ec3..1241dc1036 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysis.java @@ -49,14 +49,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysis extends TableImpl { - private static final long serialVersionUID = 1089999461; + private static final long serialVersionUID = -1691829725; /** * The reference instance of VIOLATIONANALYSIS @@ -141,13 +141,13 @@ public ViolationAnalysis(Table path, ForeignKey { - private static final long serialVersionUID = 1089999461; + private static final long serialVersionUID = -1691829725; public ViolationAnalysisPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java index 4bbea6eeb3..e30181aa8d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/ViolationAnalysisComment.java @@ -47,14 +47,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysisComment extends TableImpl { - private static final long serialVersionUID = 833389648; + private static final long serialVersionUID = 1354024210; /** * The reference instance of VIOLATIONANALYSISCOMMENT @@ -134,13 +134,13 @@ public ViolationAnalysisComment(Table path, ForeignKey { - private static final long serialVersionUID = 833389648; + private static final long serialVersionUID = 1354024210; public ViolationAnalysisCommentPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java index 90d1c2acac..895c32489f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilitiesTags.java @@ -44,14 +44,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilitiesTags extends TableImpl { - private static final long serialVersionUID = 1626926470; + private static final long serialVersionUID = -1012932092; /** * The reference instance of VULNERABILITIES_TAGS @@ -116,13 +116,13 @@ public VulnerabilitiesTags(Table path, ForeignKey { - private static final long serialVersionUID = 1626926470; + private static final long serialVersionUID = -1012932092; public VulnerabilitiesTagsPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java index 43bf41e95d..5a0dae0a74 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/Vulnerability.java @@ -57,14 +57,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class Vulnerability extends TableImpl { - private static final long serialVersionUID = 194354309; + private static final long serialVersionUID = -528883931; /** * The reference instance of VULNERABILITY @@ -274,13 +274,13 @@ public Vulnerability(Table path, ForeignKey { - private static final long serialVersionUID = 194354309; + private static final long serialVersionUID = -528883931; public VulnerabilityPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java index bc898db017..2de0065eaa 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityAlias.java @@ -42,14 +42,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityAlias extends TableImpl { - private static final long serialVersionUID = 2010552213; + private static final long serialVersionUID = 1062762774; /** * The reference instance of VULNERABILITYALIAS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java index 0f076f367b..85a3b5b1ab 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityMetrics.java @@ -38,14 +38,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityMetrics extends TableImpl { - private static final long serialVersionUID = -1647962504; + private static final long serialVersionUID = -1051268935; /** * The reference instance of VULNERABILITYMETRICS diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java index d6c218b60e..4594919db9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicy.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicy extends TableImpl { - private static final long serialVersionUID = -751906294; + private static final long serialVersionUID = 322144298; /** * The reference instance of VULNERABILITY_POLICY @@ -170,13 +170,13 @@ public VulnerabilityPolicy(Table path, ForeignKey { - private static final long serialVersionUID = -751906294; + private static final long serialVersionUID = 322144298; public VulnerabilityPolicyPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java index 823a2208db..4cf6730d8b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityPolicyBundle.java @@ -38,14 +38,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicyBundle extends TableImpl { - private static final long serialVersionUID = -653983299; + private static final long serialVersionUID = 2085813276; /** * The reference instance of VULNERABILITY_POLICY_BUNDLE diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java index 042b62043d..e0758d651e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerabilityScan.java @@ -41,14 +41,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityScan extends TableImpl { - private static final long serialVersionUID = 936592231; + private static final long serialVersionUID = 823724870; /** * The reference instance of VULNERABILITYSCAN diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java index 7f6b561bf8..ef226ac50c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftware.java @@ -48,14 +48,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftware extends TableImpl { - private static final long serialVersionUID = 1199573646; + private static final long serialVersionUID = 478732812; /** * The reference instance of VULNERABLESOFTWARE @@ -245,13 +245,13 @@ public VulnerableSoftware(Table path, ForeignKey { - private static final long serialVersionUID = 1199573646; + private static final long serialVersionUID = 478732812; public VulnerableSoftwarePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java index 476f3c573e..527da9d6a8 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/VulnerableSoftwareVulnerabilities.java @@ -45,14 +45,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftwareVulnerabilities extends TableImpl { - private static final long serialVersionUID = -587467024; + private static final long serialVersionUID = -36111600; /** * The reference instance of VULNERABLESOFTWARE_VULNERABILITIES @@ -121,13 +121,13 @@ public VulnerableSoftwareVulnerabilities(Table path, Forei value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) public static class VulnerableSoftwareVulnerabilitiesPath extends VulnerableSoftwareVulnerabilities implements Path { - private static final long serialVersionUID = -587467024; + private static final long serialVersionUID = -36111600; public VulnerableSoftwareVulnerabilitiesPath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java index 97dab01600..2625ee20ef 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/WorkflowState.java @@ -50,14 +50,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class WorkflowState extends TableImpl { - private static final long serialVersionUID = 136710125; + private static final long serialVersionUID = 363010637; /** * The reference instance of WORKFLOW_STATE @@ -152,13 +152,13 @@ public WorkflowState(Table path, ForeignKey { - private static final long serialVersionUID = 136710125; + private static final long serialVersionUID = 363010637; public WorkflowStatePath(Table path, ForeignKey childPath, InverseForeignKey parentPath) { super(path, childPath, parentPath); } diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java index 7d7ae2428d..2d06679d99 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AffectedVersionAttributionRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AffectedVersionAttributionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 830189685; + private static final long serialVersionUID = 533796436; /** * Setter for AFFECTEDVERSIONATTRIBUTION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java index c387cdcb0e..e5cbe92e23 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisCommentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AnalysisCommentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 683571869; + private static final long serialVersionUID = 1564864124; /** * Setter for ANALYSISCOMMENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java index f72bc82c6f..b2038d827d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/AnalysisRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class AnalysisRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1074618273; + private static final long serialVersionUID = 1771339838; /** * Setter for ANALYSIS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java index aef891db85..a6efa5d822 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeyRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKeyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -285420750; + private static final long serialVersionUID = 780881553; /** * Setter for APIKEY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java index 9b5a605556..113a5957e1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ApiKeysTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ApiKeysTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -2091283289; + private static final long serialVersionUID = -1229569274; /** * Setter for APIKEYS_TEAMS.TEAM_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java index e1920895e7..21d028fbc7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/BomRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class BomRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1158088535; + private static final long serialVersionUID = -106213910; /** * Setter for BOM.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java index 6ef69f9020..7f7d80cbd9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentOccurrenceRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentOccurrenceRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1566639764; + private static final long serialVersionUID = 69875541; /** * Setter for COMPONENT_OCCURRENCE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java index 2a261a2e3a..40aa410c2d 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentPropertyRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentPropertyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1894747516; + private static final long serialVersionUID = 1332589723; /** * Setter for COMPONENT_PROPERTY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java index 7043b48983..d56778a000 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1813992192; + private static final long serialVersionUID = 20605313; /** * Setter for COMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java index 174c7519aa..b92b1c1831 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ComponentsVulnerabilitiesRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ComponentsVulnerabilitiesRecord extends TableRecordImpl { - private static final long serialVersionUID = 1782821111; + private static final long serialVersionUID = 1744858838; /** * Setter for COMPONENTS_VULNERABILITIES.COMPONENT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java index 1613d9b137..c0d92ebd16 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ConfigPropertyRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ConfigPropertyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1531833329; + private static final long serialVersionUID = 1295311696; /** * Setter for CONFIGPROPERTY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java index 05ac2d25c7..0c30e5acde 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/DependencyMetricsRecord.java @@ -9,7 +9,7 @@ import javax.annotation.processing.Generated; import org.dependencytrack.persistence.jooq.generated.tables.DependencyMetrics; -import org.jooq.Record3; +import org.jooq.Record2; import org.jooq.impl.UpdatableRecordImpl; @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class DependencyMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -78726026; + private static final long serialVersionUID = 64997608; /** * Setter for DEPENDENCYMETRICS.COMPONENT_ID. @@ -500,8 +500,8 @@ public Integer getVulnerabilities() { // ------------------------------------------------------------------------- @Override - public Record3 key() { - return (Record3) super.key(); + public Record2 key() { + return (Record2) super.key(); } // ------------------------------------------------------------------------- diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java index 023facaf15..61a61f19a1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/EpssRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class EpssRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1881018208; + private static final long serialVersionUID = 1875280511; /** * Setter for EPSS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java index ceb7e1d5b9..68d1234085 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/FindingAttributionRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class FindingAttributionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1597754647; + private static final long serialVersionUID = -986843320; /** * Setter for FINDINGATTRIBUTION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java index 89084b52c3..7ebca876b1 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityAnalysisRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityAnalysisRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1886133780; + private static final long serialVersionUID = 814859541; /** * Setter for INTEGRITY_ANALYSIS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java index 9b181b743c..116c9d45e9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/IntegrityMetaComponentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class IntegrityMetaComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -2144778894; + private static final long serialVersionUID = -521695023; /** * Setter for INTEGRITY_META_COMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java index e036f8f951..51b737af88 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupLicenseRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroupLicenseRecord extends TableRecordImpl { - private static final long serialVersionUID = -449692016; + private static final long serialVersionUID = 366575441; /** * Setter for LICENSEGROUP_LICENSE.LICENSEGROUP_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java index baa58c753f..0a4c696800 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseGroupRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -2014332549; + private static final long serialVersionUID = -1523022310; /** * Setter for LICENSEGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java index 83661cb1f8..a2fde611d0 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/LicenseRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class LicenseRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -108552760; + private static final long serialVersionUID = 1138644071; /** * Setter for LICENSE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java index ed8bf95d18..64a489c52b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedLdapGroupRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedLdapGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1055111209; + private static final long serialVersionUID = 1360638856; /** * Setter for MAPPEDLDAPGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java index 7ec4319b08..d4858da750 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/MappedOidcGroupRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class MappedOidcGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -235246095; + private static final long serialVersionUID = 876479218; /** * Setter for MAPPEDOIDCGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java index 64e4242d48..dc0722b62b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationPublisherRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationPublisherRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -140065302; + private static final long serialVersionUID = -701592341; /** * Setter for NOTIFICATIONPUBLISHER.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java index e1efa0e115..28000f38b7 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleProjectsRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleProjectsRecord extends TableRecordImpl { - private static final long serialVersionUID = -458610639; + private static final long serialVersionUID = -139885710; /** * Setter for NOTIFICATIONRULE_PROJECTS.NOTIFICATIONRULE_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java index 219d6fad16..a474e1083a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1490850195; + private static final long serialVersionUID = -1505180020; /** * Setter for NOTIFICATIONRULE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java index c2b8f14a05..82da06991c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 2128918538; + private static final long serialVersionUID = 1496097227; /** * Setter for NOTIFICATIONRULE_TAGS.NOTIFICATIONRULE_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java index fde1d95331..e6d2d70d7c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/NotificationRuleTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class NotificationRuleTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 631633464; + private static final long serialVersionUID = 330605399; /** * Setter for NOTIFICATIONRULE_TEAMS.NOTIFICATIONRULE_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java index 26146fc65f..a79262a52e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/OidcGroupRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class OidcGroupRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1380876876; + private static final long serialVersionUID = 863674293; /** * Setter for OIDCGROUP.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java index ba13280d95..b88512005f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PermissionRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PermissionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1586304711; + private static final long serialVersionUID = -701052856; /** * Setter for PERMISSION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java index fcbf737aca..ed09f5ae98 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyConditionRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyConditionRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1855718319; + private static final long serialVersionUID = 1226736654; /** * Setter for POLICYCONDITION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java index a864d6911c..19d275ee45 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyProjectsRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyProjectsRecord extends TableRecordImpl { - private static final long serialVersionUID = 1289508177; + private static final long serialVersionUID = 1554469202; /** * Setter for POLICY_PROJECTS.POLICY_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java index 96d0d3311a..13d45aea40 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1255213442; + private static final long serialVersionUID = 1730537791; /** * Setter for POLICY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java index 4db995d17f..8e4ed305f3 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -718175564; + private static final long serialVersionUID = 1290267957; /** * Setter for POLICY_TAGS.POLICY_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java index 9fa503fbea..eb805c5be9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PolicyViolationRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PolicyViolationRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -2130877628; + private static final long serialVersionUID = -698016285; /** * Setter for POLICYVIOLATION.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java index 5a4a758dbc..92292da008 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/PortfolioMetricsRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class PortfolioMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -640386303; + private static final long serialVersionUID = 133730690; /** * Setter for PORTFOLIOMETRICS.COMPONENTS. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java index fc2c868a54..04d7bbed6f 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectAccessTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectAccessTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1036749248; + private static final long serialVersionUID = -1553693119; /** * Setter for PROJECT_ACCESS_TEAMS.PROJECT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java index 400af2fd9e..281adc8fd9 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectHierarchyRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectHierarchyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -407800101; + private static final long serialVersionUID = -744060998; /** * Setter for PROJECT_HIERARCHY.PARENT_PROJECT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java index 638a3418c9..83cc2efcf5 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetadataRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetadataRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -462682031; + private static final long serialVersionUID = 909539440; /** * Setter for PROJECT_METADATA.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java index bc05e10987..1e51451e76 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectMetricsRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 492620514; + private static final long serialVersionUID = 580774465; /** * Setter for PROJECTMETRICS.COMPONENTS. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java index ae353606f7..fc2f0ac9dc 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectPropertyRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectPropertyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 145578597; + private static final long serialVersionUID = 724624550; /** * Setter for PROJECT_PROPERTY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java index 18e45539ac..bd38a82264 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRecord.java @@ -22,14 +22,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1640806964; + private static final long serialVersionUID = -1244388909; /** * Setter for PROJECT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRoleBindingRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRoleBindingRecord.java deleted file mode 100644 index c3609f91c1..0000000000 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectRoleBindingRecord.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is generated by jOOQ. - */ -package org.dependencytrack.persistence.jooq.generated.tables.records; - - -import javax.annotation.processing.Generated; - -import org.dependencytrack.persistence.jooq.generated.tables.ProjectRoleBinding; -import org.jooq.impl.TableRecordImpl; - - -/** - * This class is generated by jOOQ. - */ -@Generated( - value = { - "https://www.jooq.org", - "jOOQ version:3.20.4", - "schema version:v5.6.0-27" - }, - comments = "This class is generated by jOOQ" -) -@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) -public class ProjectRoleBindingRecord extends TableRecordImpl { - - private static final long serialVersionUID = -147063056; - - /** - * Setter for PROJECT_ROLE_BINDING.USER_ID. - */ - public ProjectRoleBindingRecord setUserId(Long value) { - set(0, value); - return this; - } - - /** - * Getter for PROJECT_ROLE_BINDING.USER_ID. - */ - public Long getUserId() { - return (Long) get(0); - } - - /** - * Setter for PROJECT_ROLE_BINDING.PROJECT_ID. - */ - public ProjectRoleBindingRecord setProjectId(Long value) { - set(1, value); - return this; - } - - /** - * Getter for PROJECT_ROLE_BINDING.PROJECT_ID. - */ - public Long getProjectId() { - return (Long) get(1); - } - - /** - * Setter for PROJECT_ROLE_BINDING.ROLE_ID. - */ - public ProjectRoleBindingRecord setRoleId(Long value) { - set(2, value); - return this; - } - - /** - * Getter for PROJECT_ROLE_BINDING.ROLE_ID. - */ - public Long getRoleId() { - return (Long) get(2); - } - - // ------------------------------------------------------------------------- - // Constructors - // ------------------------------------------------------------------------- - - /** - * Create a detached UsersProjectsRolesRecord - */ - public ProjectRoleBindingRecord() { - super(ProjectRoleBinding.PROJECT_ROLE_BINDING); - } - - /** - * Create a detached, initialised UsersProjectsRolesRecord - */ - public ProjectRoleBindingRecord(Long userId, Long projectId, Long roleId) { - super(ProjectRoleBinding.PROJECT_ROLE_BINDING); - - setUserId(userId); - setProjectId(projectId); - setRoleId(roleId); - resetTouchedOnNotNull(); - } -} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java index 46ac5702e7..f2ee92422a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ProjectsTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ProjectsTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1673410517; + private static final long serialVersionUID = -1759842764; /** * Setter for PROJECTS_TAGS.TAG_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java index 65dedc05e2..ae311437f4 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryMetaComponentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RepositoryMetaComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 530816784; + private static final long serialVersionUID = -1220342319; /** * Setter for REPOSITORY_META_COMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java index df9f7ae905..21179d2234 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RepositoryRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RepositoryRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 193876256; + private static final long serialVersionUID = 1948209249; /** * Setter for REPOSITORY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java index 6dbc946de9..97e5c16b66 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RoleRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class RoleRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -404691591; + private static final long serialVersionUID = -401848680; /** * Setter for ROLE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java index 26f33eff91..aee9bf557b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/RolesPermissionsRecord.java @@ -7,7 +7,8 @@ import javax.annotation.processing.Generated; import org.dependencytrack.persistence.jooq.generated.tables.RolesPermissions; -import org.jooq.impl.TableRecordImpl; +import org.jooq.Record2; +import org.jooq.impl.UpdatableRecordImpl; /** @@ -17,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) -public class RolesPermissionsRecord extends TableRecordImpl { +public class RolesPermissionsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -268299302; + private static final long serialVersionUID = 240634674; /** * Setter for ROLES_PERMISSIONS.ROLE_ID. @@ -56,6 +57,15 @@ public Long getPermissionId() { return (Long) get(1); } + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record2 key() { + return (Record2) super.key(); + } + // ------------------------------------------------------------------------- // Constructors // ------------------------------------------------------------------------- diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java index f1a1bfa12f..a74c084b86 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -313015124; + private static final long serialVersionUID = 943332205; /** * Setter for SERVICECOMPONENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java index e80071bfc7..408c84d821 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ServiceComponentsVulnerabilitiesRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ServiceComponentsVulnerabilitiesRecord extends TableRecordImpl { - private static final long serialVersionUID = -1453803659; + private static final long serialVersionUID = -1421916682; /** * Setter for diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java index 2c80cafc04..74589d4c02 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TagRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TagRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1486904060; + private static final long serialVersionUID = 1662148963; /** * Setter for TAG.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java index d7ae92976b..6813dcc152 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TeamRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1435240628; + private static final long serialVersionUID = -586163501; /** * Setter for TEAM.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java index a87f56dd76..685f70a059 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/TeamsPermissionsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class TeamsPermissionsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1282451951; + private static final long serialVersionUID = 1277670350; /** * Setter for TEAMS_PERMISSIONS.TEAM_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java index dfad702be8..d278e9c72b 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectEffectivePermissionsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UserProjectEffectivePermissionsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -934414569; + private static final long serialVersionUID = 2058346840; /** * Setter for USER_PROJECT_EFFECTIVE_PERMISSIONS.PROJECT_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectRolesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectRolesRecord.java new file mode 100644 index 0000000000..41874b37be --- /dev/null +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserProjectRolesRecord.java @@ -0,0 +1,106 @@ +/* + * This file is generated by jOOQ. + */ +package org.dependencytrack.persistence.jooq.generated.tables.records; + + +import javax.annotation.processing.Generated; + +import org.dependencytrack.persistence.jooq.generated.tables.UserProjectRoles; +import org.jooq.Record3; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "https://www.jooq.org", + "jOOQ version:3.20.4", + "schema version:v5.6.0-28" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class UserProjectRolesRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = 306934379; + + /** + * Setter for USER_PROJECT_ROLES.USER_ID. + */ + public UserProjectRolesRecord setUserId(Long value) { + set(0, value); + return this; + } + + /** + * Getter for USER_PROJECT_ROLES.USER_ID. + */ + public Long getUserId() { + return (Long) get(0); + } + + /** + * Setter for USER_PROJECT_ROLES.PROJECT_ID. + */ + public UserProjectRolesRecord setProjectId(Long value) { + set(1, value); + return this; + } + + /** + * Getter for USER_PROJECT_ROLES.PROJECT_ID. + */ + public Long getProjectId() { + return (Long) get(1); + } + + /** + * Setter for USER_PROJECT_ROLES.ROLE_ID. + */ + public UserProjectRolesRecord setRoleId(Long value) { + set(2, value); + return this; + } + + /** + * Getter for USER_PROJECT_ROLES.ROLE_ID. + */ + public Long getRoleId() { + return (Long) get(2); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record3 key() { + return (Record3) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached UserProjectRolesRecord + */ + public UserProjectRolesRecord() { + super(UserProjectRoles.USER_PROJECT_ROLES); + } + + /** + * Create a detached, initialised UserProjectRolesRecord + */ + public UserProjectRolesRecord(Long userId, Long projectId, Long roleId) { + super(UserProjectRoles.USER_PROJECT_ROLES); + + setUserId(userId); + setProjectId(projectId); + setRoleId(roleId); + resetTouchedOnNotNull(); + } +} diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java index ffe1e818ef..0b830d85ac 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UserRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UserRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1987326126; + private static final long serialVersionUID = -1740382829; /** * Setter for USER.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java index 49b4bcd603..1bbb055f79 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersPermissionsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersPermissionsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1191546457; + private static final long serialVersionUID = -1196328058; /** * Setter for USERS_PERMISSIONS.USER_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java index 8b04fc466e..4ec4808ea0 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/UsersTeamsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class UsersTeamsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -800688593; + private static final long serialVersionUID = -670012722; /** * Setter for USERS_TEAMS.USER_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java index 8e72850505..d39bf1ed33 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VexRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VexRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 656810192; + private static final long serialVersionUID = -636790319; /** * Setter for VEX.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java index 9f9a7df49d..8e65c8728a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisCommentRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysisCommentRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 392460294; + private static final long serialVersionUID = -1995255835; /** * Setter for VIOLATIONANALYSISCOMMENT.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java index 839867fd5c..262f98ed7e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/ViolationAnalysisRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class ViolationAnalysisRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1891849923; + private static final long serialVersionUID = 195262434; /** * Setter for VIOLATIONANALYSIS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java index 8942679101..f8d9897300 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilitiesTagsRecord.java @@ -18,14 +18,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilitiesTagsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 822864282; + private static final long serialVersionUID = -1339201735; /** * Setter for VULNERABILITIES_TAGS.TAG_ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java index 6009c692f9..37b0a3569a 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityAliasRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityAliasRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1497308906; + private static final long serialVersionUID = 1404593559; /** * Setter for VULNERABILITYALIAS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java index 6fa5df32a3..4d7b353a71 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityMetricsRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityMetricsRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 336038556; + private static final long serialVersionUID = -829325573; /** * Setter for VULNERABILITYMETRICS.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java index 5e135259c6..c6b6ebc7cc 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyBundleRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicyBundleRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = -1375266263; + private static final long serialVersionUID = -1454362966; /** * Setter for VULNERABILITY_POLICY_BUNDLE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java index 1d2efcb45e..652be14f7c 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityPolicyRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityPolicyRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1120893212; + private static final long serialVersionUID = 634551739; /** * Setter for VULNERABILITY_POLICY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java index 04072978c9..13ae5cfe59 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityRecord.java @@ -23,14 +23,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1739870155; + private static final long serialVersionUID = -582473302; /** * Setter for VULNERABILITY.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java index a94a8bece1..d4551db8a6 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerabilityScanRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerabilityScanRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 147284591; + private static final long serialVersionUID = 2011955662; /** * Setter for VULNERABILITYSCAN.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java index 7f8e29a080..ee27597f50 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareRecord.java @@ -20,14 +20,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftwareRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 638654342; + private static final long serialVersionUID = 351395365; /** * Setter for VULNERABLESOFTWARE.ID. diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java index f4ab34c9d1..00776b58e4 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/VulnerableSoftwareVulnerabilitiesRecord.java @@ -17,14 +17,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class VulnerableSoftwareVulnerabilitiesRecord extends TableRecordImpl { - private static final long serialVersionUID = -1792385758; + private static final long serialVersionUID = 1760646115; /** * Setter for diff --git a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java index 8974817812..2028c5c42e 100644 --- a/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java +++ b/persistence-jooq/src/main/java/org/dependencytrack/persistence/jooq/generated/tables/records/WorkflowStateRecord.java @@ -21,14 +21,14 @@ value = { "https://www.jooq.org", "jOOQ version:3.20.4", - "schema version:v5.6.0-27" + "schema version:v5.6.0-28" }, comments = "This class is generated by jOOQ" ) @SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) public class WorkflowStateRecord extends UpdatableRecordImpl { - private static final long serialVersionUID = 1804473797; + private static final long serialVersionUID = 99722404; /** * Setter for WORKFLOW_STATE.ID. diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index d634bea3b5..e6e97278e2 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -34,7 +34,7 @@ - + @@ -42,7 +42,7 @@ - + UPDATE "PROJECT" SET "AUTHORS" = JSON_BUILD_ARRAY(JSON_BUILD_OBJECT('name', "AUTHOR"))::TEXT @@ -61,7 +61,7 @@ - + @@ -146,7 +146,7 @@ - + UPDATE "PROJECT" SET "INACTIVE_SINCE" = NOW() WHERE "ACTIVE" IS FALSE @@ -218,19 +218,19 @@ - + - + - + @@ -1245,7 +1245,7 @@ - DO $$ + DO $$ BEGIN PERFORM remove_duplicate_rows('APIKEYS_TEAMS', 'TEAM_ID', 'APIKEY_ID'); PERFORM remove_duplicate_rows('LDAPUSERS_PERMISSIONS', 'LDAPUSER_ID', 'PERMISSION_ID'); @@ -2340,7 +2340,21 @@ - + + + + + + + @@ -2361,67 +2375,53 @@ - + validatePrimaryKey="true" validateForeignKey="true" /> - + validatePrimaryKey="true" validateForeignKey="true" /> - - - - - - - - - + - + validatePrimaryKey="true" validateForeignKey="true" /> - + validatePrimaryKey="true" validateForeignKey="true" /> - + validatePrimaryKey="true" validateForeignKey="true" /> - - - - - - - - - -- Helper function to recalculate all user permissions for a project. -- Called by trigger functions to update the values in the USER_PROJECT_EFFECTIVE_PERMISSIONS table. @@ -2438,7 +2438,7 @@ INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" ("USER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" - FROM "PROJECT_ROLE_BINDING" upr + FROM "USER_PROJECT_ROLES" upr INNER JOIN "ROLES_PERMISSIONS" rp ON rp."ROLE_ID" = upr."ROLE_ID" INNER JOIN "PERMISSION" p @@ -2464,14 +2464,14 @@ INTO project_ids FROM ( SELECT upr."PROJECT_ID" - FROM "PROJECT_ROLE_BINDING" upr + FROM "USER_PROJECT_ROLES" upr INNER JOIN old_table ON old_table."ROLE_ID" = upr."ROLE_ID" ) sub; ELSE SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") INTO project_ids - FROM "PROJECT_ROLE_BINDING" + FROM "USER_PROJECT_ROLES" WHERE "ROLE_ID" = ANY(role_ids); END IF; @@ -2497,14 +2497,14 @@ INTO project_ids FROM ( SELECT upr."PROJECT_ID" - FROM "PROJECT_ROLE_BINDING" upr + FROM "USER_PROJECT_ROLES" upr INNER JOIN new_table ON new_table."ROLE_ID" = upr."ROLE_ID" ) sub; ELSE SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") INTO project_ids - FROM "PROJECT_ROLE_BINDING" + FROM "USER_PROJECT_ROLES" WHERE "ROLE_ID" = ANY(role_ids); END IF; @@ -2534,7 +2534,7 @@ INTO project_ids FROM ( SELECT upr."PROJECT_ID" - FROM "PROJECT_ROLE_BINDING" upr + FROM "USER_PROJECT_ROLES" upr INNER JOIN new_table ON new_table."ROLE_ID" = upr."ROLE_ID" FULL OUTER JOIN old_table @@ -2543,7 +2543,7 @@ ELSE SELECT ARRAY_AGG(DISTINCT "PROJECT_ID") INTO project_ids - FROM "PROJECT_ROLE_BINDING" + FROM "USER_PROJECT_ROLES" WHERE "ROLE_ID" = ANY(role_ids); END IF; @@ -2554,23 +2554,23 @@ - -- INSERT trigger for PROJECT_ROLE_BINDING + -- INSERT trigger for USER_PROJECT_ROLES CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_insert - AFTER INSERT ON "PROJECT_ROLE_BINDING" + AFTER INSERT ON "USER_PROJECT_ROLES" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); - -- DELETE trigger for PROJECT_ROLE_BINDING + -- DELETE trigger for USER_PROJECT_ROLES CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_delete - AFTER DELETE ON "PROJECT_ROLE_BINDING" + AFTER DELETE ON "USER_PROJECT_ROLES" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); - -- UPDATE trigger for PROJECT_ROLE_BINDING + -- UPDATE trigger for USER_PROJECT_ROLES CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_update - AFTER UPDATE ON "PROJECT_ROLE_BINDING" + AFTER UPDATE ON "USER_PROJECT_ROLES" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_update(); From 62a889bf076b25cf8d32fc47ba7e44a1e2d3ed49 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Fri, 30 May 2025 11:02:38 -0600 Subject: [PATCH 31/45] refactor: renamed RoleProjectRequest to ModifyUserProjectRoleRequest - chore: test cleanup - chore: address PR comments Signed-off-by: Allen Shearin --- .../java/org/dependencytrack/model/Role.java | 3 +- .../model/UserProjectRole.java | 20 +- .../persistence/DefaultObjectGenerator.java | 4 +- .../resources/v1/UserResource.java | 6 +- ...java => ModifyUserProjectRoleRequest.java} | 2 +- .../persistence/RoleQueryManagerTest.java | 198 ++++-------------- .../resources/v1/RoleResourceTest.java | 36 +--- .../v1/UserResourceAuthenticatedTest.java | 10 +- 8 files changed, 77 insertions(+), 202 deletions(-) rename apiserver/src/main/java/org/dependencytrack/resources/v1/vo/{RoleProjectRequest.java => ModifyUserProjectRoleRequest.java} (97%) diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 8cee1170eb..1d785c5365 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -142,9 +142,8 @@ public String toString() { .map(permission -> permission.getName()) .toList(); - return "%s{id=%d, uuid='%s', name='%s', permissions=%s}".formatted( + return "%s{uuid='%s', name='%s', permissions=%s}".formatted( getClass().getSimpleName(), - id, uuid, name, permissionStrings); diff --git a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java index cc69aefd1d..4538bdd0be 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java @@ -74,14 +74,6 @@ public void setUsers(List users) { this.users = users; } - public void addUsers(User... users) { - this.users = Objects.requireNonNullElse(this.users, new ArrayList()); - this.users = Stream.concat(this.users.stream(), Arrays.stream(users)) - .distinct() - .sorted(Comparator.comparing(User::getUsername)) - .toList(); - } - public Role getRole() { return role; } @@ -98,4 +90,16 @@ public void setProject(Project project) { this.project = project; } + @Override + public String toString() { + // var userStrings = users.stream() + // .map(user -> user.getUsername()) + // .toList(); + + return "%s{role='%s', project='%s'}".formatted( + getClass().getSimpleName(), + role, + project); + //userStrings); + } } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java index cdb638f6e7..b266208407 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java @@ -302,7 +302,7 @@ private void loadDefaultPersonas(final QueryManager qm) { ManagedUser admin = qm.createManagedUser("admin", "Administrator", "admin@localhost", new String(PasswordService.createHash("admin".toCharArray())), true, true, false); - for (var name : new String[] { "Administrators", "Portfolio Managers", "Automation", "Badge Viewers" }) { + for (var name : DEFAULT_TEAM_PERMISSIONS.keySet()) { LOGGER.debug("Creating team: " + name); var team = qm.createTeam(name); @@ -345,7 +345,7 @@ private void loadDefaultRoles(final QueryManager qm) { LOGGER.info("Adding default roles to datastore"); - for (var name : new String[] { "Project Admin", "Project Auditor", "Project Editor", "Project Viewer" }) { + for (var name : DEFAULT_ROLE_PERMISSIONS.keySet()) { LOGGER.debug("Creating role: " + name); qm.createRole(name, getPermissionsByName(DEFAULT_ROLE_PERMISSIONS.get(name))); } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 05b9e6b2e9..84c61a3224 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -61,7 +61,7 @@ import org.dependencytrack.proto.notification.v1.UserSubject; import org.dependencytrack.resources.v1.problems.AccessManagementProblemDetails; import org.dependencytrack.resources.v1.problems.ProblemDetails; -import org.dependencytrack.resources.v1.vo.RoleProjectRequest; +import org.dependencytrack.resources.v1.vo.ModifyUserProjectRoleRequest; import org.dependencytrack.resources.v1.vo.TeamsSetRequest; import org.owasp.security.logging.SecurityMarkers; @@ -877,7 +877,7 @@ private UserSubject buildUserSubject(final String username, final String email) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response assignProjectRoleToUser( - @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { + @Parameter(description = "User, Role and Project information", required = true) @Valid ModifyUserProjectRoleRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); final User user = qm.getUser(request.username()); @@ -935,7 +935,7 @@ public Response assignProjectRoleToUser( }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response removeProjectRoleFromUser( - @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { + @Parameter(description = "User, Role and Project information", required = true) @Valid ModifyUserProjectRoleRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); final User user = qm.getUser(request.username()); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java similarity index 97% rename from apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java rename to apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java index 2b31e7fbe8..2165bc730d 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java @@ -30,7 +30,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; -public record RoleProjectRequest( +public record ModifyUserProjectRoleRequest( @Schema(requiredMode = Schema.RequiredMode.REQUIRED) @JsonDeserialize(using = TrimmedStringDeserializer.class) @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS_PLUS, message = "The username may only contain printable characters") diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 380f37ff66..f4b8a4b9e8 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -26,9 +26,7 @@ import alpine.model.Permission; import alpine.server.auth.PasswordService; -import java.text.DateFormat; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -43,21 +41,13 @@ public class RoleQueryManagerTest extends PersistenceCapableTest { - private static final String TEST_ROLE_PASSWORD_HASH = new String(PasswordService.createHash("testuser".toCharArray())); + private static final String TEST_ROLE_PASSWORD_HASH = new String( + PasswordService.createHash("testuser".toCharArray())); @Test public void testCreateRole() { - final var readPermission = new Permission(); - readPermission.setId(1); - readPermission.setName("read"); - readPermission.setDescription("permission to read"); - qm.persist(readPermission); - - final var writePermission = new Permission(); - writePermission.setId(2); - writePermission.setName("write"); - writePermission.setDescription("permission to write"); - qm.persist(writePermission); + final Permission readPermission = qm.createPermission("read", "permission to read"); + final Permission writePermission = qm.createPermission("write", "permission to write"); List expectedPermissionsList = Arrays.asList( readPermission, @@ -69,40 +59,24 @@ public void testCreateRole() { @Test public void testGetRoles() { - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); - - final var ownerRole = new Role(); - ownerRole.setId(2); - ownerRole.setName("owner"); - qm.persist(ownerRole); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + final Role ownerRole = qm.createRole("owner", new ArrayList()); List expectedRoles = Arrays.asList( maintainerRole, ownerRole); List actualRoles = qm.getRoles(); - List actualRolesMutable = new ArrayList(); - for (Role r : actualRoles) { - actualRolesMutable.add(r); - } - Assert.assertEquals(expectedRoles, actualRolesMutable); + Assert.assertNotNull(actualRoles); + Assert.assertFalse(actualRoles.isEmpty()); + Assert.assertEquals(expectedRoles, actualRoles); } @Test public void testGetRole() { - final var wrongRole = new Role(); - wrongRole.setId(1); - wrongRole.setName("maintainer"); - qm.persist(wrongRole); - - final var expectedRole = new Role(); - expectedRole.setId(2); - expectedRole.setName("owner"); - qm.persist(expectedRole); + final Role wrongRole = qm.createRole("maintainer", new ArrayList()); + final Role expectedRole = qm.createRole("owner", new ArrayList()); String expectedRoleUuid = expectedRole.getUuid().toString(); @@ -113,25 +87,10 @@ public void testGetRole() { @Test public void testGetUserRoles() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); - - final var expectedRole = new Role(); - expectedRole.setId(1); - expectedRole.setName("maintainer"); - qm.persist(expectedRole); + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role expectedRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(testUser, expectedRole, testProject); @@ -143,41 +102,25 @@ public void testGetUserRoles() throws ParseException { @Test public void testGetUnassignedProjects() throws ParseException { - String testUserName = "test-user"; - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername(testUserName); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Project unassignedProject1 = qm.createProject("test-project-1", "Test Description 1", "1.0.0", null, null, + null, + null, false, false); - final var unassignedProject1 = new Project(); - unassignedProject1.setId(1); - unassignedProject1.setName("test-project-1"); - qm.persist(unassignedProject1); + final Project unassignedProject2 = qm.createProject("test-project-2", "Test Description 3", "1.0.0", null, null, + null, + null, false, false); - final var assignedProject = new Project(); - assignedProject.setId(2); - assignedProject.setName("test-project-2"); - qm.persist(assignedProject); - - final var unassignedProject2 = new Project(); - unassignedProject2.setId(3); - unassignedProject2.setName("test-project-3"); - qm.persist(unassignedProject2); + final Project assignedProject = qm.createProject("test-project-3", "Test Description 2", "1.0.0", null, null, + null, + null, false, false); qm.addRoleToUser(testUser, maintainerRole, assignedProject); List expectedProjects = Arrays.asList(unassignedProject1, unassignedProject2); - List actualProjects = qm.getUnassignedProjects(testUserName); + List actualProjects = qm.getUnassignedProjects(testUser.getUsername()); // Sort both lists by project name before asserting equivalence expectedProjects.sort((p1, p2) -> p1.getName().compareTo(p2.getName())); @@ -191,23 +134,9 @@ public void testGetUnassignedProjects() throws ParseException { @Test public void testGetUnassignedRolePermissions() throws ParseException { - final var readPermission = new Permission(); - readPermission.setId(1); - readPermission.setName("read"); - readPermission.setDescription("permission to read"); - qm.persist(readPermission); - - final var writePermission = new Permission(); - writePermission.setId(2); - writePermission.setName("write"); - writePermission.setDescription("permission to write"); - qm.persist(writePermission); - - final var partyPermission = new Permission(); - partyPermission.setId(3); - partyPermission.setName("party"); - partyPermission.setDescription("permission to party"); - qm.persist(partyPermission); + final Permission readPermission = qm.createPermission("read", "permission to read"); + final Permission writePermission = qm.createPermission("write", "permission to write"); + final Permission partyPermission = qm.createPermission("party", "permission to party"); List expectedPermissionsList = Arrays.asList( readPermission, @@ -218,19 +147,9 @@ public void testGetUnassignedRolePermissions() throws ParseException { writePermission, partyPermission)); - final var assistantRegionalManagerRole = new Role(); - assistantRegionalManagerRole.setId(1); - assistantRegionalManagerRole.setName("maintainer"); - assistantRegionalManagerRole.setPermissions(allPermissions); - qm.persist(assistantRegionalManagerRole); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); + final Role assistantRegionalManagerRole = qm.createRole("maintainer", allPermissions.stream().toList()); + + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); testUser.setPermissions(expectedPermissionsList); qm.persist(testUser); @@ -243,10 +162,7 @@ public void testGetUnassignedRolePermissions() throws ParseException { @Test public void testUpdateRole() { - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); Role actualRole = qm.updateRole(maintainerRole); @@ -255,25 +171,10 @@ public void testUpdateRole() { @Test public void testAddRoleToUser() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); - - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(testUser, maintainerRole, testProject); @@ -287,25 +188,10 @@ public void testAddRoleToUser() throws ParseException { @Test public void testRemoveRoleFromUser() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); - - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(testUser, maintainerRole, testProject); Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java index 51f4f2279e..0f924027f8 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -18,9 +18,7 @@ */ package org.dependencytrack.resources.v1; -import java.text.DateFormat; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -31,7 +29,6 @@ import org.dependencytrack.ResourceTest; import org.dependencytrack.auth.Permissions; import org.dependencytrack.persistence.DefaultObjectGenerator; -import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; import org.junit.Before; @@ -140,42 +137,31 @@ public void updateRoleTest() { public void deleteRoleTest() { List rolePermissions = new ArrayList(); Role role = qm.createRole("My Role", rolePermissions); - Response response = jersey.target(V1_ROLE).request() + Response response = jersey.target(V1_ROLE + "/" + role.getUuid()).request() .header(X_API_KEY, apiKey) - .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) // HACK - .method("DELETE", Entity.entity(role, MediaType.APPLICATION_JSON)); // HACK + .method("DELETE"); // Hack: Workaround to https://github.com/eclipse-ee4j/jersey/issues/3798 Assert.assertEquals(204, response.getStatus(), 0); } @Test public void getUserRolesTest() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_USER_PASSWORD_HASH); - qm.persist(testUser); - - final var expectedRole = new Role(); - expectedRole.setId(1); + final Project testProject = qm.createProject("Test Project", "Test Description", "1.0.0", null, null, null, + null, false, false); + ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); + + final Role expectedRole = new Role(); expectedRole.setName("maintainer"); qm.persist(expectedRole); - qm.addRoleToUser(testUser, expectedRole, testProject); + qm.addRoleToUser(user, expectedRole, testProject); - Response response = jersey.target(V1_ROLE + "/test-user/roles").request() + Response response = jersey.target(V1_ROLE + "/roleuser3/role").request() .header(X_API_KEY, apiKey) .get(Response.class); + Assert.assertEquals(200, response.getStatus(), 0); + JsonArray json = parseJsonArray(response); Assert.assertNotNull(json); Assert.assertEquals(1, json.size()); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java index afadc885a6..de48f7a22c 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java @@ -33,7 +33,7 @@ import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; import org.dependencytrack.notification.NotificationConstants; -import org.dependencytrack.resources.v1.vo.RoleProjectRequest; +import org.dependencytrack.resources.v1.vo.ModifyUserProjectRoleRequest; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; @@ -764,7 +764,7 @@ public void assignProjectRoleToUserTest() { Role role = qm.createRole("Test Role", Collections.emptyList()); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString()); @@ -793,7 +793,7 @@ public void assignProjectRoleToUserAlreadyAssignedTest() { qm.addRoleToUser(user, role, project); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() @@ -816,7 +816,7 @@ public void removeProjectRoleFromUserTest() { Role role = qm.createRole("Test Role 3", Collections.emptyList()); qm.addRoleToUser(user, role, project); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() @@ -839,7 +839,7 @@ public void removeProjectRoleFromUserNotAssignedTest() { null,null,null,false); Role role = qm.createRole("Test Role 4", Collections.emptyList()); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() From 85b4379bc0a5026d1ba2fdba9193da6e1d732554 Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Fri, 30 May 2025 13:17:18 -0500 Subject: [PATCH 32/45] refactor: change List field to User Signed-off-by: Jonathan Howard --- .../model/UserProjectRole.java | 80 +++---- .../persistence/DefaultObjectGenerator.java | 2 +- .../persistence/QueryManager.java | 12 +- .../persistence/RoleQueryManager.java | 127 ++++------- .../resources/v1/RoleResource.java | 9 +- .../resources/v1/UserResource.java | 6 +- ...leRequest.java => RoleProjectRequest.java} | 2 +- .../persistence/RoleQueryManagerTest.java | 200 ++++++++++++++---- .../resources/v1/RoleResourceTest.java | 34 ++- .../v1/UserResourceAuthenticatedTest.java | 10 +- .../resources/migration/changelog-v5.6.0.xml | 25 ++- 11 files changed, 291 insertions(+), 216 deletions(-) rename apiserver/src/main/java/org/dependencytrack/resources/v1/vo/{ModifyUserProjectRoleRequest.java => RoleProjectRequest.java} (97%) diff --git a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java index 4538bdd0be..9fa870215f 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java @@ -18,22 +18,16 @@ */ package org.dependencytrack.model; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import alpine.model.User; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; import javax.jdo.annotations.Column; -import javax.jdo.annotations.Element; -import javax.jdo.annotations.Extension; -import javax.jdo.annotations.Order; +import javax.jdo.annotations.IdGeneratorStrategy; +import javax.jdo.annotations.Index; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.Persistent; import javax.jdo.annotations.PrimaryKey; @@ -46,60 +40,70 @@ */ @PersistenceCapable(table = "USER_PROJECT_ROLES") @JsonInclude(JsonInclude.Include.NON_NULL) -@PrimaryKey(name = "USER_PROJECT_ROLES_PK", columns = { - @Column(name = "USER_ID"), - @Column(name = "PROJECT_ID"), - @Column(name = "ROLE_ID") -}) +@Index(name = "USER_PROJECT_ROLES_IDX", unique = "true", members = { "user", "project", "role" }) public class UserProjectRole implements Serializable { + public UserProjectRole() {} + + public UserProjectRole(final User user, final Project project, final Role role) { + this.user = user; + this.project = project; + this.role = role; + } + + @PrimaryKey + @Persistent(valueStrategy = IdGeneratorStrategy.NATIVE) + @JsonIgnore + private long id; + @Persistent(defaultFetchGroup = "true") - @Column(name = "ROLE_ID", allowsNull = "false") - private Role role; + @Column(name = "USER_ID") + private User user; @Persistent(defaultFetchGroup = "true") - @Column(name = "PROJECT_ID", allowsNull = "false") + @Column(name = "PROJECT_ID") private Project project; @Persistent(defaultFetchGroup = "true") - @Element(column = "USER_ID") - @Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "username ASC")) - private List users; + @Column(name = "ROLE_ID") + private Role role; - public List getUsers() { - return users; + public long getId() { + return id; } - public void setUsers(List users) { - this.users = users; + public void setId(final long id) { + this.id = id; } - public Role getRole() { - return role; + public User getUser() { + return user; } - public void setRole(Role role) { - this.role = role; + public void setUser(final User user) { + this.user = user; } public Project getProject() { return project; } - public void setProject(Project project) { + public void setProject(final Project project) { this.project = project; } + public Role getRole() { + return role; + } + + public void setRole(final Role role) { + this.role = role; + } + @Override public String toString() { - // var userStrings = users.stream() - // .map(user -> user.getUsername()) - // .toList(); - - return "%s{role='%s', project='%s'}".formatted( - getClass().getSimpleName(), - role, - project); - //userStrings); + return "%s{user=%s, project=%s, role=%s}".formatted( + getClass().getSimpleName(), user.getUsername(), project, role); } + } diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java index b266208407..3c513c2c1b 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java @@ -43,8 +43,8 @@ import java.time.Duration; import java.time.Instant; -import java.util.Collections; import java.time.LocalDate; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index e11eba7e9b..67cbcd9dbd 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -487,12 +487,10 @@ protected Set getRoleIds(final Principal principal, final Project project) .filter("project.id == :projectId && users.contains(:principal)") .setNamedParameters(Map.ofEntries( Map.entry("principal", principal), - Map.entry("projectId", project.getId()))); + Map.entry("projectId", project.getId()))) + .result("role.id"); - return Set.of(executeAndCloseList(query).stream() - .map(UserProjectRole::getRole) - .map(Role::getId) - .toArray(Long[]::new)); + return Set.copyOf(executeAndCloseResultList(query, Long.class)); } /** @@ -1135,8 +1133,8 @@ public List getUnassignedRolePermissions(final Role role) { return getRoleQueryManager().getUnassignedRolePermissions(role); } - public List getUserRoles(final User user) { - return getRoleQueryManager().getUserRoles(user); + public List getUserRoles(final String username) { + return getRoleQueryManager().getUserRoles(username); } public boolean removeRoleFromUser(final User user, final Role role, final Project project) { diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index 0f8d908312..fed17397ce 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -18,17 +18,12 @@ */ package org.dependencytrack.persistence; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.jdo.PersistenceManager; import javax.jdo.Query; -import javax.jdo.datastore.JDOConnection; import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; @@ -67,15 +62,11 @@ public Role createRole(final String name, final List permissions) { @Override public boolean addPermissionToRole(final Role role, final Permission permission) { - Query query = pm.newQuery(Query.SQL, /* language=sql */ """ - SELECT EXISTS( - SELECT 1 - FROM "ROLES_PERMISSIONS" - WHERE "ROLE_ID" = ? - AND "PERMISSION_ID" = ? - ) - """) - .setParameters(role.getId(), permission.getId()); + final Query query = pm.newQuery(Permission.class) + .variables("org.dependencytrack.model.Role role") + .filter("role.id == :roleId && role.permissions.contains(this) && this.id == :permissionId") + .setParameters(role.getId(), permission.getId()) + .result("count(this) > 0"); if (executeAndCloseResultUnique(query, Boolean.class)) return false; @@ -116,49 +107,39 @@ public Role getRole(final String uuid) { } @Override - public List getUserRoles(final User user) { - final Query query = pm.newQuery(Query.SQL, /* language=sql */ """ - SELECT upr."USER_ID", upr."PROJECT_ID", upr."ROLE_ID" - FROM "USER_PROJECT_ROLES" upr - INNER JOIN "USER" u - ON u."ID" = upr."USER_ID" - WHERE u."USERNAME" = ? - """) - .setParameters(user.getUsername()); + public List getUserRoles(final String username) { + final Query query = pm.newQuery(UserProjectRole.class) + .filter("user.username == :username") + .setParameters(username); - return executeAndCloseResultList(query, UserProjectRole.class); + return executeAndCloseList(query); } public List getUnassignedProjects(final String username) { final Query query = pm.newQuery(Query.SQL, /* language=sql */ """ SELECT p."ID", p."NAME", p."VERSION", p."UUID" FROM "PROJECT" p - LEFT JOIN "USER_PROJECT_ROLES" upr - ON upr."PROJECT_ID" = p."ID" - LEFT JOIN "USER" u - ON u."ID" = upr."USER_ID" - WHERE u."USERNAME" != ? - OR u."USERNAME" IS NULL - """) - .setParameters(username); + WHERE NOT EXISTS ( + SELECT 1 + FROM "USER_PROJECT_ROLES" upr + INNER JOIN "USER" u + ON u."ID" = upr."USER_ID" + WHERE upr."PROJECT_ID" = p."ID" + AND u."USERNAME" = ? + ) + """) + .setParameters(username); return executeAndCloseResultList(query, Project.class); } public List getUnassignedRolePermissions(final Role role) { - final List permissions = new ArrayList<>(); - - final var permissionNames = role.getPermissions().stream() - .map(Permission::getName) - .toList(); - final Query query = pm.newQuery(Permission.class) - .filter("!:permissionNames.contains(name)") - .setParameters(permissionNames); + .filter("role.id == :roleId && !role.permissions.contains(this)") + .variables("org.dependencytrack.model.Role role") + .setParameters(role.getId()); - permissions.addAll(executeAndCloseList(query)); - - return permissions; + return executeAndCloseList(query); } @Override @@ -174,56 +155,26 @@ public Role updateRole(final Role transientRole) { @Override public boolean addRoleToUser(final User user, final Role role, final Project project) { - Query query = pm.newQuery(Query.SQL, /* language=sql */ """ - SELECT EXISTS( - SELECT 1 - FROM "USER_PROJECT_ROLES" - WHERE "USER_ID" = ? - AND "PROJECT_ID" = ? - AND "ROLE_ID" = ? - ) - """) - .setParameters(user.getId(), project.getId(), role.getId()); + Query query = pm.newQuery(UserProjectRole.class) + .filter("user.id == :userId && project.id == :projectId && role.id == :roleId") + .setParameters(user.getId(), project.getId(), role.getId()) + .result("count(this) > 0"); if (executeAndCloseResultUnique(query, Boolean.class)) return false; - final JDOConnection jdoConnection = pm.getDataStoreConnection(); - final var nativeConnection = (Connection) jdoConnection.getNativeConnection(); - - try (final PreparedStatement ps = nativeConnection.prepareStatement( - /* language=sql */ """ - INSERT INTO "USER_PROJECT_ROLES" - ("USER_ID", "PROJECT_ID", "ROLE_ID") - VALUES - (?, ?, ?) - """)) { - ps.setLong(1, user.getId()); - ps.setLong(2, project.getId()); - ps.setLong(3, role.getId()); - ps.execute(); - } catch (SQLException e) { - throw new RuntimeException("Failed to add role: user='%s' / project='%s' / role='%s'".formatted( - user.getUsername(), project.toString(), role.getName()), e); - } finally { - jdoConnection.close(); - } + persist(new UserProjectRole(user, project, role)); return true; } @Override public boolean removeRoleFromUser(final User user, final Role role, final Project project) { - final Query query = pm.newQuery(Query.SQL, /* language=sql */ """ - SELECT * - FROM "USER_PROJECT_ROLES" - WHERE "USER_ID" = ? - AND "PROJECT_ID" = ? - AND "ROLE_ID" = ? - """) + final Query query = pm.newQuery(UserProjectRole.class) + .filter("user.id == :userId && project.id == :projectId && role.id == :roleId") .setParameters(user.getId(), project.getId(), role.getId()); - final UserProjectRole projectRole = executeAndCloseResultUnique(query, UserProjectRole.class); + final UserProjectRole projectRole = executeAndCloseUnique(query); if (projectRole == null) return false; @@ -235,16 +186,10 @@ public boolean removeRoleFromUser(final User user, final Role role, final Projec @Override public boolean userProjectRoleExists(final User user, final Role role, final Project project) { - Query query = pm.newQuery(Query.SQL, /* language=sql */ """ - SELECT EXISTS( - SELECT 1 - FROM "USER_PROJECT_ROLES" - WHERE "USER_ID" = ? - AND "PROJECT_ID" = ? - AND "ROLE_ID" = ? - ) - """) - .setParameters(user.getId(), project.getId(), role.getId()); + final Query query = pm.newQuery(UserProjectRole.class) + .filter("user.id == :userId && project.id == :projectId && role.id == :roleId") + .setParameters(user.getId(), project.getId(), role.getId()) + .result("count(this) > 0"); return executeAndCloseResultUnique(query, Boolean.class); } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index e41661cdd2..54b31261d3 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -55,7 +55,6 @@ import org.owasp.security.logging.SecurityMarkers; import alpine.model.Permission; -import alpine.model.User; import java.util.List; import java.util.Map; @@ -254,13 +253,7 @@ public Response deleteRole( public Response getUserRoles( @Parameter(description = "A valid username", required = true) @PathParam("username") String username) { try (QueryManager qm = new QueryManager()) { - User user = qm.getUser(username); - if (user == null) { - LOGGER.warn("User not found: " + username); - return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); - } - - List roles = qm.getUserRoles(user); + List roles = qm.getUserRoles(username); if (roles == null || roles.isEmpty()) { LOGGER.info("No roles found for user: " + username); return Response.ok(List.of()).build(); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 84c61a3224..05b9e6b2e9 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -61,7 +61,7 @@ import org.dependencytrack.proto.notification.v1.UserSubject; import org.dependencytrack.resources.v1.problems.AccessManagementProblemDetails; import org.dependencytrack.resources.v1.problems.ProblemDetails; -import org.dependencytrack.resources.v1.vo.ModifyUserProjectRoleRequest; +import org.dependencytrack.resources.v1.vo.RoleProjectRequest; import org.dependencytrack.resources.v1.vo.TeamsSetRequest; import org.owasp.security.logging.SecurityMarkers; @@ -877,7 +877,7 @@ private UserSubject buildUserSubject(final String username, final String email) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response assignProjectRoleToUser( - @Parameter(description = "User, Role and Project information", required = true) @Valid ModifyUserProjectRoleRequest request) { + @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); final User user = qm.getUser(request.username()); @@ -935,7 +935,7 @@ public Response assignProjectRoleToUser( }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response removeProjectRoleFromUser( - @Parameter(description = "User, Role and Project information", required = true) @Valid ModifyUserProjectRoleRequest request) { + @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); final User user = qm.getUser(request.username()); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java similarity index 97% rename from apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java rename to apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java index 2165bc730d..2b31e7fbe8 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java @@ -30,7 +30,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; -public record ModifyUserProjectRoleRequest( +public record RoleProjectRequest( @Schema(requiredMode = Schema.RequiredMode.REQUIRED) @JsonDeserialize(using = TrimmedStringDeserializer.class) @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS_PLUS, message = "The username may only contain printable characters") diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index f4b8a4b9e8..259bd05f5c 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -26,7 +26,9 @@ import alpine.model.Permission; import alpine.server.auth.PasswordService; +import java.text.DateFormat; import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -41,13 +43,21 @@ public class RoleQueryManagerTest extends PersistenceCapableTest { - private static final String TEST_ROLE_PASSWORD_HASH = new String( - PasswordService.createHash("testuser".toCharArray())); + private static final String TEST_ROLE_PASSWORD_HASH = new String(PasswordService.createHash("testuser".toCharArray())); @Test public void testCreateRole() { - final Permission readPermission = qm.createPermission("read", "permission to read"); - final Permission writePermission = qm.createPermission("write", "permission to write"); + final var readPermission = new Permission(); + readPermission.setId(1); + readPermission.setName("read"); + readPermission.setDescription("permission to read"); + qm.persist(readPermission); + + final var writePermission = new Permission(); + writePermission.setId(2); + writePermission.setName("write"); + writePermission.setDescription("permission to write"); + qm.persist(writePermission); List expectedPermissionsList = Arrays.asList( readPermission, @@ -59,24 +69,40 @@ public void testCreateRole() { @Test public void testGetRoles() { - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); - final Role ownerRole = qm.createRole("owner", new ArrayList()); + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); + + final var ownerRole = new Role(); + ownerRole.setId(2); + ownerRole.setName("owner"); + qm.persist(ownerRole); List expectedRoles = Arrays.asList( maintainerRole, ownerRole); List actualRoles = qm.getRoles(); + List actualRolesMutable = new ArrayList(); + for (Role r : actualRoles) { + actualRolesMutable.add(r); + } - Assert.assertNotNull(actualRoles); - Assert.assertFalse(actualRoles.isEmpty()); - Assert.assertEquals(expectedRoles, actualRoles); + Assert.assertEquals(expectedRoles, actualRolesMutable); } @Test public void testGetRole() { - final Role wrongRole = qm.createRole("maintainer", new ArrayList()); - final Role expectedRole = qm.createRole("owner", new ArrayList()); + final var wrongRole = new Role(); + wrongRole.setId(1); + wrongRole.setName("maintainer"); + qm.persist(wrongRole); + + final var expectedRole = new Role(); + expectedRole.setId(2); + expectedRole.setName("owner"); + qm.persist(expectedRole); String expectedRoleUuid = expectedRole.getUuid().toString(); @@ -87,14 +113,29 @@ public void testGetRole() { @Test public void testGetUserRoles() throws ParseException { - final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, - null, false, false); - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); - final Role expectedRole = qm.createRole("maintainer", new ArrayList()); + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); + qm.persist(testUser); + + final var expectedRole = new Role(); + expectedRole.setId(1); + expectedRole.setName("maintainer"); + qm.persist(expectedRole); qm.addRoleToUser(testUser, expectedRole, testProject); - List actualRoles = qm.getUserRoles(testUser); + List actualRoles = qm.getUserRoles(testUser.getUsername()); Assert.assertEquals(actualRoles.size(), 1); Assert.assertEquals(expectedRole.toString(), actualRoles.get(0).getRole().toString()); @@ -102,25 +143,41 @@ public void testGetUserRoles() throws ParseException { @Test public void testGetUnassignedProjects() throws ParseException { - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + String testUserName = "test-user"; + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername(testUserName); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); + qm.persist(testUser); - final Project unassignedProject1 = qm.createProject("test-project-1", "Test Description 1", "1.0.0", null, null, - null, - null, false, false); + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); - final Project unassignedProject2 = qm.createProject("test-project-2", "Test Description 3", "1.0.0", null, null, - null, - null, false, false); + final var unassignedProject1 = new Project(); + unassignedProject1.setId(1); + unassignedProject1.setName("test-project-1"); + qm.persist(unassignedProject1); - final Project assignedProject = qm.createProject("test-project-3", "Test Description 2", "1.0.0", null, null, - null, - null, false, false); + final var assignedProject = new Project(); + assignedProject.setId(2); + assignedProject.setName("test-project-2"); + qm.persist(assignedProject); + + final var unassignedProject2 = new Project(); + unassignedProject2.setId(3); + unassignedProject2.setName("test-project-3"); + qm.persist(unassignedProject2); qm.addRoleToUser(testUser, maintainerRole, assignedProject); List expectedProjects = Arrays.asList(unassignedProject1, unassignedProject2); - List actualProjects = qm.getUnassignedProjects(testUser.getUsername()); + List actualProjects = qm.getUnassignedProjects(testUserName); // Sort both lists by project name before asserting equivalence expectedProjects.sort((p1, p2) -> p1.getName().compareTo(p2.getName())); @@ -134,9 +191,23 @@ public void testGetUnassignedProjects() throws ParseException { @Test public void testGetUnassignedRolePermissions() throws ParseException { - final Permission readPermission = qm.createPermission("read", "permission to read"); - final Permission writePermission = qm.createPermission("write", "permission to write"); - final Permission partyPermission = qm.createPermission("party", "permission to party"); + final var readPermission = new Permission(); + readPermission.setId(1); + readPermission.setName("read"); + readPermission.setDescription("permission to read"); + qm.persist(readPermission); + + final var writePermission = new Permission(); + writePermission.setId(2); + writePermission.setName("write"); + writePermission.setDescription("permission to write"); + qm.persist(writePermission); + + final var partyPermission = new Permission(); + partyPermission.setId(3); + partyPermission.setName("party"); + partyPermission.setDescription("permission to party"); + qm.persist(partyPermission); List expectedPermissionsList = Arrays.asList( readPermission, @@ -147,9 +218,19 @@ public void testGetUnassignedRolePermissions() throws ParseException { writePermission, partyPermission)); - final Role assistantRegionalManagerRole = qm.createRole("maintainer", allPermissions.stream().toList()); - - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final var assistantRegionalManagerRole = new Role(); + assistantRegionalManagerRole.setId(1); + assistantRegionalManagerRole.setName("maintainer"); + assistantRegionalManagerRole.setPermissions(allPermissions); + qm.persist(assistantRegionalManagerRole); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); testUser.setPermissions(expectedPermissionsList); qm.persist(testUser); @@ -162,7 +243,10 @@ public void testGetUnassignedRolePermissions() throws ParseException { @Test public void testUpdateRole() { - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); Role actualRole = qm.updateRole(maintainerRole); @@ -171,10 +255,25 @@ public void testUpdateRole() { @Test public void testAddRoleToUser() throws ParseException { - final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, - null, false, false); - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); + qm.persist(testUser); + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); qm.addRoleToUser(testUser, maintainerRole, testProject); @@ -188,10 +287,25 @@ public void testAddRoleToUser() throws ParseException { @Test public void testRemoveRoleFromUser() throws ParseException { - final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, - null, false, false); - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword(TEST_ROLE_PASSWORD_HASH); + qm.persist(testUser); + + final var maintainerRole = new Role(); + maintainerRole.setId(1); + maintainerRole.setName("maintainer"); + qm.persist(maintainerRole); qm.addRoleToUser(testUser, maintainerRole, testProject); Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java index 0f924027f8..2a7b81d178 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -18,7 +18,9 @@ */ package org.dependencytrack.resources.v1; +import java.text.DateFormat; import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -29,6 +31,7 @@ import org.dependencytrack.ResourceTest; import org.dependencytrack.auth.Permissions; import org.dependencytrack.persistence.DefaultObjectGenerator; +import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; import org.junit.Before; @@ -139,29 +142,40 @@ public void deleteRoleTest() { Role role = qm.createRole("My Role", rolePermissions); Response response = jersey.target(V1_ROLE + "/" + role.getUuid()).request() .header(X_API_KEY, apiKey) - .method("DELETE"); + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) // HACK + .method("DELETE", Entity.entity(role, MediaType.APPLICATION_JSON)); // HACK // Hack: Workaround to https://github.com/eclipse-ee4j/jersey/issues/3798 Assert.assertEquals(204, response.getStatus(), 0); } @Test public void getUserRolesTest() throws ParseException { - final Project testProject = qm.createProject("Test Project", "Test Description", "1.0.0", null, null, null, - null, false, false); - ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); - - final Role expectedRole = new Role(); + final var testProject = new Project(); + testProject.setId(1); + testProject.setName("test-project"); + testProject.setVersion("1.0.0"); + qm.persist(testProject); + + final var testUser = new ManagedUser(); + testUser.setFullname("test user created for testing"); + testUser.setId(1); + testUser.setUsername("test-user"); + DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); + testUser.setLastPasswordChange(dateFormatter.parse("20250324")); + testUser.setPassword(TEST_USER_PASSWORD_HASH); + qm.persist(testUser); + + final var expectedRole = new Role(); + expectedRole.setId(1); expectedRole.setName("maintainer"); qm.persist(expectedRole); - qm.addRoleToUser(user, expectedRole, testProject); + qm.addRoleToUser(testUser, expectedRole, testProject); - Response response = jersey.target(V1_ROLE + "/roleuser3/role").request() + Response response = jersey.target(V1_ROLE + "/test-user/role").request() .header(X_API_KEY, apiKey) .get(Response.class); - Assert.assertEquals(200, response.getStatus(), 0); - JsonArray json = parseJsonArray(response); Assert.assertNotNull(json); Assert.assertEquals(1, json.size()); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java index de48f7a22c..afadc885a6 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java @@ -33,7 +33,7 @@ import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; import org.dependencytrack.notification.NotificationConstants; -import org.dependencytrack.resources.v1.vo.ModifyUserProjectRoleRequest; +import org.dependencytrack.resources.v1.vo.RoleProjectRequest; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; @@ -764,7 +764,7 @@ public void assignProjectRoleToUserTest() { Role role = qm.createRole("Test Role", Collections.emptyList()); - ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( + RoleProjectRequest request = new RoleProjectRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString()); @@ -793,7 +793,7 @@ public void assignProjectRoleToUserAlreadyAssignedTest() { qm.addRoleToUser(user, role, project); - ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( + RoleProjectRequest request = new RoleProjectRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() @@ -816,7 +816,7 @@ public void removeProjectRoleFromUserTest() { Role role = qm.createRole("Test Role 3", Collections.emptyList()); qm.addRoleToUser(user, role, project); - ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( + RoleProjectRequest request = new RoleProjectRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() @@ -839,7 +839,7 @@ public void removeProjectRoleFromUserNotAssignedTest() { null,null,null,false); Role role = qm.createRole("Test Role 4", Collections.emptyList()); - ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( + RoleProjectRequest request = new RoleProjectRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index e6e97278e2..622ab3389c 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -2394,34 +2394,41 @@ + + + + - + validateForeignKey="true" /> - + validateForeignKey="true" /> - + validateForeignKey="true" /> + + + + + + -- Helper function to recalculate all user permissions for a project. -- Called by trigger functions to update the values in the USER_PROJECT_EFFECTIVE_PERMISSIONS table. From 5e008f123141072116873046acb2782ecfc77008 Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Fri, 30 May 2025 13:44:16 -0500 Subject: [PATCH 33/45] chore: remove unused method Signed-off-by: Jonathan Howard --- .../persistence/QueryManager.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 67cbcd9dbd..9fff08269a 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -477,22 +477,6 @@ public QueryManager withL2CacheDisabled() { return this; } - /** - * Get the IDs of the {@link UserProjectRole}s a given {@link Principal} is a member of. - * - * @return A {@link Set} of {@link UserProjectRole} IDs - */ - protected Set getRoleIds(final Principal principal, final Project project) { - final Query query = pm.newQuery(UserProjectRole.class) - .filter("project.id == :projectId && users.contains(:principal)") - .setNamedParameters(Map.ofEntries( - Map.entry("principal", principal), - Map.entry("projectId", project.getId()))) - .result("role.id"); - - return Set.copyOf(executeAndCloseResultList(query, Long.class)); - } - /** * Get the IDs of the {@link Team}s a given {@link Principal} is a member of. * From f377f1585e12ea5a40b1b05e923537d7afc91125 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Fri, 30 May 2025 13:52:58 -0600 Subject: [PATCH 34/45] chore: redo test cleanup and name change Signed-off-by: Allen Shearin --- .../resources/v1/UserResource.java | 6 +- ...java => ModifyUserProjectRoleRequest.java} | 2 +- .../persistence/RoleQueryManagerTest.java | 198 ++++-------------- .../resources/v1/RoleResourceTest.java | 34 +-- .../v1/UserResourceAuthenticatedTest.java | 10 +- 5 files changed, 61 insertions(+), 189 deletions(-) rename apiserver/src/main/java/org/dependencytrack/resources/v1/vo/{RoleProjectRequest.java => ModifyUserProjectRoleRequest.java} (97%) diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 05b9e6b2e9..84c61a3224 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -61,7 +61,7 @@ import org.dependencytrack.proto.notification.v1.UserSubject; import org.dependencytrack.resources.v1.problems.AccessManagementProblemDetails; import org.dependencytrack.resources.v1.problems.ProblemDetails; -import org.dependencytrack.resources.v1.vo.RoleProjectRequest; +import org.dependencytrack.resources.v1.vo.ModifyUserProjectRoleRequest; import org.dependencytrack.resources.v1.vo.TeamsSetRequest; import org.owasp.security.logging.SecurityMarkers; @@ -877,7 +877,7 @@ private UserSubject buildUserSubject(final String username, final String email) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response assignProjectRoleToUser( - @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { + @Parameter(description = "User, Role and Project information", required = true) @Valid ModifyUserProjectRoleRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); final User user = qm.getUser(request.username()); @@ -935,7 +935,7 @@ public Response assignProjectRoleToUser( }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response removeProjectRoleFromUser( - @Parameter(description = "User, Role and Project information", required = true) @Valid RoleProjectRequest request) { + @Parameter(description = "User, Role and Project information", required = true) @Valid ModifyUserProjectRoleRequest request) { try (QueryManager qm = new QueryManager()) { final Role role = qm.getObjectByUuid(Role.class, request.role()); final User user = qm.getUser(request.username()); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java similarity index 97% rename from apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java rename to apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java index 2b31e7fbe8..2165bc730d 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/RoleProjectRequest.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/vo/ModifyUserProjectRoleRequest.java @@ -30,7 +30,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; -public record RoleProjectRequest( +public record ModifyUserProjectRoleRequest( @Schema(requiredMode = Schema.RequiredMode.REQUIRED) @JsonDeserialize(using = TrimmedStringDeserializer.class) @Pattern(regexp = RegexSequence.Definition.PRINTABLE_CHARS_PLUS, message = "The username may only contain printable characters") diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 259bd05f5c..12a046ce2e 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -26,9 +26,7 @@ import alpine.model.Permission; import alpine.server.auth.PasswordService; -import java.text.DateFormat; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -43,21 +41,13 @@ public class RoleQueryManagerTest extends PersistenceCapableTest { - private static final String TEST_ROLE_PASSWORD_HASH = new String(PasswordService.createHash("testuser".toCharArray())); + private static final String TEST_ROLE_PASSWORD_HASH = new String( + PasswordService.createHash("testuser".toCharArray())); @Test public void testCreateRole() { - final var readPermission = new Permission(); - readPermission.setId(1); - readPermission.setName("read"); - readPermission.setDescription("permission to read"); - qm.persist(readPermission); - - final var writePermission = new Permission(); - writePermission.setId(2); - writePermission.setName("write"); - writePermission.setDescription("permission to write"); - qm.persist(writePermission); + final Permission readPermission = qm.createPermission("read", "permission to read"); + final Permission writePermission = qm.createPermission("write", "permission to write"); List expectedPermissionsList = Arrays.asList( readPermission, @@ -69,40 +59,24 @@ public void testCreateRole() { @Test public void testGetRoles() { - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); - - final var ownerRole = new Role(); - ownerRole.setId(2); - ownerRole.setName("owner"); - qm.persist(ownerRole); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + final Role ownerRole = qm.createRole("owner", new ArrayList()); List expectedRoles = Arrays.asList( maintainerRole, ownerRole); List actualRoles = qm.getRoles(); - List actualRolesMutable = new ArrayList(); - for (Role r : actualRoles) { - actualRolesMutable.add(r); - } - Assert.assertEquals(expectedRoles, actualRolesMutable); + Assert.assertNotNull(actualRoles); + Assert.assertFalse(actualRoles.isEmpty()); + Assert.assertEquals(expectedRoles, actualRoles); } @Test public void testGetRole() { - final var wrongRole = new Role(); - wrongRole.setId(1); - wrongRole.setName("maintainer"); - qm.persist(wrongRole); - - final var expectedRole = new Role(); - expectedRole.setId(2); - expectedRole.setName("owner"); - qm.persist(expectedRole); + final Role wrongRole = qm.createRole("maintainer", new ArrayList()); + final Role expectedRole = qm.createRole("owner", new ArrayList()); String expectedRoleUuid = expectedRole.getUuid().toString(); @@ -113,25 +87,10 @@ public void testGetRole() { @Test public void testGetUserRoles() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); - - final var expectedRole = new Role(); - expectedRole.setId(1); - expectedRole.setName("maintainer"); - qm.persist(expectedRole); + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role expectedRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(testUser, expectedRole, testProject); @@ -143,41 +102,25 @@ public void testGetUserRoles() throws ParseException { @Test public void testGetUnassignedProjects() throws ParseException { - String testUserName = "test-user"; - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername(testUserName); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Project unassignedProject1 = qm.createProject("test-project-1", "Test Description 1", "1.0.0", null, null, + null, + null, false, false); - final var unassignedProject1 = new Project(); - unassignedProject1.setId(1); - unassignedProject1.setName("test-project-1"); - qm.persist(unassignedProject1); + final Project unassignedProject2 = qm.createProject("test-project-2", "Test Description 3", "1.0.0", null, null, + null, + null, false, false); - final var assignedProject = new Project(); - assignedProject.setId(2); - assignedProject.setName("test-project-2"); - qm.persist(assignedProject); - - final var unassignedProject2 = new Project(); - unassignedProject2.setId(3); - unassignedProject2.setName("test-project-3"); - qm.persist(unassignedProject2); + final Project assignedProject = qm.createProject("test-project-3", "Test Description 2", "1.0.0", null, null, + null, + null, false, false); qm.addRoleToUser(testUser, maintainerRole, assignedProject); List expectedProjects = Arrays.asList(unassignedProject1, unassignedProject2); - List actualProjects = qm.getUnassignedProjects(testUserName); + List actualProjects = qm.getUnassignedProjects(testUser.getUsername()); // Sort both lists by project name before asserting equivalence expectedProjects.sort((p1, p2) -> p1.getName().compareTo(p2.getName())); @@ -191,23 +134,9 @@ public void testGetUnassignedProjects() throws ParseException { @Test public void testGetUnassignedRolePermissions() throws ParseException { - final var readPermission = new Permission(); - readPermission.setId(1); - readPermission.setName("read"); - readPermission.setDescription("permission to read"); - qm.persist(readPermission); - - final var writePermission = new Permission(); - writePermission.setId(2); - writePermission.setName("write"); - writePermission.setDescription("permission to write"); - qm.persist(writePermission); - - final var partyPermission = new Permission(); - partyPermission.setId(3); - partyPermission.setName("party"); - partyPermission.setDescription("permission to party"); - qm.persist(partyPermission); + final Permission readPermission = qm.createPermission("read", "permission to read"); + final Permission writePermission = qm.createPermission("write", "permission to write"); + final Permission partyPermission = qm.createPermission("party", "permission to party"); List expectedPermissionsList = Arrays.asList( readPermission, @@ -218,19 +147,9 @@ public void testGetUnassignedRolePermissions() throws ParseException { writePermission, partyPermission)); - final var assistantRegionalManagerRole = new Role(); - assistantRegionalManagerRole.setId(1); - assistantRegionalManagerRole.setName("maintainer"); - assistantRegionalManagerRole.setPermissions(allPermissions); - qm.persist(assistantRegionalManagerRole); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); + final Role assistantRegionalManagerRole = qm.createRole("maintainer", allPermissions.stream().toList()); + + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); testUser.setPermissions(expectedPermissionsList); qm.persist(testUser); @@ -243,10 +162,7 @@ public void testGetUnassignedRolePermissions() throws ParseException { @Test public void testUpdateRole() { - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); Role actualRole = qm.updateRole(maintainerRole); @@ -255,25 +171,10 @@ public void testUpdateRole() { @Test public void testAddRoleToUser() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); - - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(testUser, maintainerRole, testProject); @@ -287,25 +188,10 @@ public void testAddRoleToUser() throws ParseException { @Test public void testRemoveRoleFromUser() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_ROLE_PASSWORD_HASH); - qm.persist(testUser); - - final var maintainerRole = new Role(); - maintainerRole.setId(1); - maintainerRole.setName("maintainer"); - qm.persist(maintainerRole); + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(testUser, maintainerRole, testProject); Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java index 2a7b81d178..0f924027f8 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -18,9 +18,7 @@ */ package org.dependencytrack.resources.v1; -import java.text.DateFormat; import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -31,7 +29,6 @@ import org.dependencytrack.ResourceTest; import org.dependencytrack.auth.Permissions; import org.dependencytrack.persistence.DefaultObjectGenerator; -import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; import org.junit.Before; @@ -142,40 +139,29 @@ public void deleteRoleTest() { Role role = qm.createRole("My Role", rolePermissions); Response response = jersey.target(V1_ROLE + "/" + role.getUuid()).request() .header(X_API_KEY, apiKey) - .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) // HACK - .method("DELETE", Entity.entity(role, MediaType.APPLICATION_JSON)); // HACK + .method("DELETE"); // Hack: Workaround to https://github.com/eclipse-ee4j/jersey/issues/3798 Assert.assertEquals(204, response.getStatus(), 0); } @Test public void getUserRolesTest() throws ParseException { - final var testProject = new Project(); - testProject.setId(1); - testProject.setName("test-project"); - testProject.setVersion("1.0.0"); - qm.persist(testProject); - - final var testUser = new ManagedUser(); - testUser.setFullname("test user created for testing"); - testUser.setId(1); - testUser.setUsername("test-user"); - DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd"); - testUser.setLastPasswordChange(dateFormatter.parse("20250324")); - testUser.setPassword(TEST_USER_PASSWORD_HASH); - qm.persist(testUser); - - final var expectedRole = new Role(); - expectedRole.setId(1); + final Project testProject = qm.createProject("Test Project", "Test Description", "1.0.0", null, null, null, + null, false, false); + ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); + + final Role expectedRole = new Role(); expectedRole.setName("maintainer"); qm.persist(expectedRole); - qm.addRoleToUser(testUser, expectedRole, testProject); + qm.addRoleToUser(user, expectedRole, testProject); - Response response = jersey.target(V1_ROLE + "/test-user/role").request() + Response response = jersey.target(V1_ROLE + "/roleuser3/role").request() .header(X_API_KEY, apiKey) .get(Response.class); + Assert.assertEquals(200, response.getStatus(), 0); + JsonArray json = parseJsonArray(response); Assert.assertNotNull(json); Assert.assertEquals(1, json.size()); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java index afadc885a6..de48f7a22c 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/UserResourceAuthenticatedTest.java @@ -33,7 +33,7 @@ import org.dependencytrack.model.Project; import org.dependencytrack.model.Role; import org.dependencytrack.notification.NotificationConstants; -import org.dependencytrack.resources.v1.vo.RoleProjectRequest; +import org.dependencytrack.resources.v1.vo.ModifyUserProjectRoleRequest; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; @@ -764,7 +764,7 @@ public void assignProjectRoleToUserTest() { Role role = qm.createRole("Test Role", Collections.emptyList()); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString()); @@ -793,7 +793,7 @@ public void assignProjectRoleToUserAlreadyAssignedTest() { qm.addRoleToUser(user, role, project); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() @@ -816,7 +816,7 @@ public void removeProjectRoleFromUserTest() { Role role = qm.createRole("Test Role 3", Collections.emptyList()); qm.addRoleToUser(user, role, project); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() @@ -839,7 +839,7 @@ public void removeProjectRoleFromUserNotAssignedTest() { null,null,null,false); Role role = qm.createRole("Test Role 4", Collections.emptyList()); - RoleProjectRequest request = new RoleProjectRequest( + ModifyUserProjectRoleRequest request = new ModifyUserProjectRoleRequest( user.getUsername(), role.getUuid().toString(), project.getUuid().toString() From b6685d0d9ed96b116ab920c1ab0f752c834fa387 Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Fri, 30 May 2025 15:27:41 -0500 Subject: [PATCH 35/45] style: fix codacy style issues Signed-off-by: Jonathan Howard --- .../dependencytrack/model/UserProjectRole.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java index 9fa870215f..82258642c1 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java @@ -43,14 +43,6 @@ @Index(name = "USER_PROJECT_ROLES_IDX", unique = "true", members = { "user", "project", "role" }) public class UserProjectRole implements Serializable { - public UserProjectRole() {} - - public UserProjectRole(final User user, final Project project, final Role role) { - this.user = user; - this.project = project; - this.role = role; - } - @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.NATIVE) @JsonIgnore @@ -68,6 +60,14 @@ public UserProjectRole(final User user, final Project project, final Role role) @Column(name = "ROLE_ID") private Role role; + public UserProjectRole() {} + + public UserProjectRole(final User user, final Project project, final Role role) { + this.user = user; + this.project = project; + this.role = role; + } + public long getId() { return id; } From ffa2975c5410b2fd2c2d8be10f6807f1c65259f9 Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Sat, 31 May 2025 13:38:47 -0500 Subject: [PATCH 36/45] style: formatting Signed-off-by: Jonathan Howard --- .../resources/v1/PermissionResource.java | 36 ++++++----------- .../resources/v1/RoleResource.java | 39 ++++-------------- .../resources/v1/UserResource.java | 40 +++++-------------- 3 files changed, 31 insertions(+), 84 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java index 8c1bf66b5c..e2d9cde396 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java @@ -233,20 +233,14 @@ public Response addPermissionToTeam( @Path("/{permission}/role/{uuid}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Operation( - description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" - ) + @Operation(description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

") @ApiResponses(value = { - @ApiResponse( - responseCode = "200", - description = "The updated role", - content = @Content(schema = @Schema(implementation = Role.class)) - ), + @ApiResponse(responseCode = "200", description = "The updated role", content = @Content(schema = @Schema(implementation = Role.class))), @ApiResponse(responseCode = "304", description = "The role already has the specified permission assigned"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) - @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE }) public Response removePermissionFromRole( @Parameter(description = "A valid role uuid", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -254,13 +248,13 @@ public Response removePermissionFromRole( @PathParam("permission") String permissionName) { try (QueryManager qm = new QueryManager()) { Role role = qm.getObjectByUuid(Role.class, uuid); - if (role == null) { + if (role == null) return Response.status(Response.Status.NOT_FOUND).entity("The role could not be found.").build(); - } + final Permission permission = qm.getPermission(permissionName); - if (permission == null) { + if (permission == null) return Response.status(Response.Status.NOT_FOUND).entity("The permission could not be found.").build(); - } + final Set permissions = role.getPermissions(); if (permissions != null && permissions.contains(permission)) { permissions.remove(permission); @@ -269,7 +263,8 @@ public Response removePermissionFromRole( super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Removed permission for role: " + role.getName() + " / permission: " + permission.getName()); return Response.ok(role).build(); } - return Response.status(Response.Status.NOT_MODIFIED).build(); + + return Response.notModified().build(); } } @@ -277,20 +272,15 @@ public Response removePermissionFromRole( @Path("/{permission}/role/{uuid}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Operation( - description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" - ) + @Operation(description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") @ApiResponses(value = { - @ApiResponse( - responseCode = "200", - description = "The updated role", - content = @Content(schema = @Schema(implementation = Role.class)) + @ApiResponse(responseCode = "200", description = "The updated role", content = @Content(schema = @Schema(implementation = Role.class)) ), @ApiResponse(responseCode = "304", description = "The role already has the specified permission assigned"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) - @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response addPermissionToRole( @Parameter(description = "A valid role uuid", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -306,7 +296,7 @@ public Response addPermissionToRole( return Response.status(Response.Status.NOT_FOUND).entity("The permission could not be found.").build(); if (!qm.addPermissionToRole(role, permission)) - return Response.status(Response.Status.NOT_MODIFIED).build(); + return Response.notModified().build(); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added permission for role: " + role.getName() + " / permission: " + permission.getName()); diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index 54b31261d3..6ed507a6ab 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -54,12 +54,7 @@ import org.owasp.security.logging.SecurityMarkers; -import alpine.model.Permission; - import java.util.List; -import java.util.Map; - -import javax.jdo.Query; /** * JAX-RS resources for processing roles. @@ -138,37 +133,22 @@ public Response getRole( @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "The created role", content = @Content(schema = @Schema(implementation = Role.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse(responseCode = "409", description = "The Role already exists"), + @ApiResponse(responseCode = "409", description = "The role already exists"), }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE }) public Response createRole(@Valid CreateRoleRequest request) { try (QueryManager qm = new QueryManager()) { - boolean roleExists = qm.getRoleByName(request.name()) != null; - - if (roleExists) { + if (qm.getRoleByName(request.name()) != null) return Response.status(Response.Status.CONFLICT) .entity(String.format("Role '%s' already exists", request.name())) .build(); - } - - List permissionNames = request.permissions() - .stream() - .map(Permissions::name) - .toList(); - final Query query = qm.getPersistenceManager().newQuery(Permission.class) - .filter(":permissions.contains(name)") - .setNamedParameters(Map.of("permissions", permissionNames)) - .orderBy("name asc"); + final Role role = qm.createRole(request.name(), + qm.getPermissionsByName(request.permissions() + .stream() + .map(Permissions::name) + .toList())); - final List requestedPermissions; - try { - requestedPermissions = List.copyOf(query.executeList()); - } finally { - query.closeAll(); - } - - final Role role = qm.createRole(request.name(), requestedPermissions); super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Role created: " + role.getName()); return Response.status(Response.Status.CREATED).entity(role).build(); @@ -182,10 +162,7 @@ public Response createRole(@Valid CreateRoleRequest request) { summary = "Updates a role's fields", description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") @ApiResponses(value = { - @ApiResponse( - responseCode = "200", - description = "The updated role", - content = @Content(schema = @Schema(implementation = Role.class))), + @ApiResponse(responseCode = "200", description = "The updated role", content = @Content(schema = @Schema(implementation = Role.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The role could not be found") }) diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 84c61a3224..127d06478f 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -863,17 +863,10 @@ private UserSubject buildUserSubject(final String username, final String email) description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { - @ApiResponse( - responseCode = "200", - description = "User with the specified role assigned or updated", - content = @Content(schema = @Schema(implementation = User.class))), + @ApiResponse(responseCode = "200", description = "User with the specified role assigned or updated", content = @Content(schema = @Schema(implementation = User.class))), @ApiResponse(responseCode = "304", description = "The user already has this role for the project."), @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse( - responseCode = "404", - description = "The user, role, or project could not be found", - content = @Content(schema = @Schema(implementation = AccessManagementProblemDetails.class)) - ) + @ApiResponse(responseCode = "404", description = "The user, role, or project could not be found", content = @Content(schema = @Schema(implementation = AccessManagementProblemDetails.class))) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response assignProjectRoleToUser( @@ -888,15 +881,12 @@ public Response assignProjectRoleToUser( if (user == null) problems.add("user"); if (project == null) problems.add("project"); - if (!problems.isEmpty()) { - ProblemDetails problem = new AccessManagementProblemDetails( + if (!problems.isEmpty()) + return new AccessManagementProblemDetails( Response.Status.NOT_FOUND.getStatusCode(), "Invalid role, user or project", "One or more variables could not be found", - problems); - - return problem.toResponse(); - } + problems).toResponse(); if (qm.userProjectRoleExists(user, role, project)) return Response.notModified().build(); @@ -921,17 +911,10 @@ public Response assignProjectRoleToUser( description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { - @ApiResponse( - responseCode = "204", - description = "The specified role was successfully removed from the user" - ), + @ApiResponse(responseCode = "204", description = "The specified role was successfully removed from the user"), @ApiResponse(responseCode = "304", description = "The user is not a member of the specified role for the project"), @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse( - responseCode = "404", - description = "The user, role, or project could not be found", - content = @Content(schema = @Schema(implementation = AccessManagementProblemDetails.class)) - ) + @ApiResponse(responseCode = "404",description = "The user, role, or project could not be found",content = @Content(schema = @Schema(implementation = AccessManagementProblemDetails.class))) }) @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) public Response removeProjectRoleFromUser( @@ -946,15 +929,12 @@ public Response removeProjectRoleFromUser( if (user == null) problems.add("user"); if (project == null) problems.add("project"); - if (!problems.isEmpty()) { - ProblemDetails problem = new AccessManagementProblemDetails( + if (!problems.isEmpty()) + return new AccessManagementProblemDetails( Response.Status.NOT_FOUND.getStatusCode(), "Invalid role, user or project", "One or more variables could not be found", - problems); - - return problem.toResponse(); - } + problems).toResponse(); boolean removed = qm.removeRoleFromUser(user, role, project); if (!removed) return Response.notModified().build(); From 3bf1846f4ddee442332191df0060ad661358f085 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Sat, 31 May 2025 14:22:52 -0600 Subject: [PATCH 37/45] tests: add additional unit tests Signed-off-by: Allen Shearin --- .../java/org/dependencytrack/model/Role.java | 3 +- .../model/UserProjectRole.java | 2 +- .../PersistenceCapableTest.java | 4 + .../org/dependencytrack/model/RoleTest.java | 125 ++++++++++++++++ .../model/UserProjectRoleTest.java | 112 ++++++++++++++ .../persistence/QueryManagerTest.java | 3 +- .../persistence/RoleQueryManagerTest.java | 141 ++++++++++-------- .../resources/v1/RoleResourceTest.java | 74 +++++++-- 8 files changed, 389 insertions(+), 75 deletions(-) create mode 100644 apiserver/src/test/java/org/dependencytrack/model/RoleTest.java create mode 100644 apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 1d785c5365..31e69d07a9 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -139,7 +139,8 @@ public void setUuid(UUID uuid) { @Override public String toString() { var permissionStrings = permissions.stream() - .map(permission -> permission.getName()) + .sorted((p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName())) + .map(Permission::getName) .toList(); return "%s{uuid='%s', name='%s', permissions=%s}".formatted( diff --git a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java index 82258642c1..e01aa74a0e 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java @@ -103,7 +103,7 @@ public void setRole(final Role role) { @Override public String toString() { return "%s{user=%s, project=%s, role=%s}".formatted( - getClass().getSimpleName(), user.getUsername(), project, role); + getClass().getSimpleName(), user.getUsername(), project.getName(), role.getName()); } } diff --git a/apiserver/src/test/java/org/dependencytrack/PersistenceCapableTest.java b/apiserver/src/test/java/org/dependencytrack/PersistenceCapableTest.java index 49fc363dd5..421a53cd20 100644 --- a/apiserver/src/test/java/org/dependencytrack/PersistenceCapableTest.java +++ b/apiserver/src/test/java/org/dependencytrack/PersistenceCapableTest.java @@ -19,6 +19,7 @@ package org.dependencytrack; import alpine.Config; +import alpine.server.auth.PasswordService; import alpine.server.persistence.PersistenceManagerFactory; import org.apache.kafka.clients.producer.MockProducer; import org.datanucleus.PropertyNames; @@ -43,6 +44,9 @@ public abstract class PersistenceCapableTest { protected MockProducer kafkaMockProducer; protected QueryManager qm; + protected static final String TEST_PASSWORD_HASH = new String( + PasswordService.createHash("testuser".toCharArray())); + @BeforeClass public static void init() { Config.enableUnitTests(); diff --git a/apiserver/src/test/java/org/dependencytrack/model/RoleTest.java b/apiserver/src/test/java/org/dependencytrack/model/RoleTest.java new file mode 100644 index 0000000000..93782f66f1 --- /dev/null +++ b/apiserver/src/test/java/org/dependencytrack/model/RoleTest.java @@ -0,0 +1,125 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ + +package org.dependencytrack.model; + +import alpine.model.Permission; + +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; + +public class RoleTest { + + @Test + public void testGetAndSetId() { + Role role = new Role(); + role.setId(123L); + Assert.assertEquals(123L, role.getId()); + } + + @Test + public void testGetAndSetName() { + Role role = new Role(); + role.setName("Test Role"); + Assert.assertEquals("Test Role", role.getName()); + } + + @Test + public void testGetAndSetPermissions() { + Role role = new Role(); + Permission permission1 = new Permission(); + permission1.setName("Permission1"); + + Permission permission2 = new Permission(); + permission2.setName("Permission2"); + + Set permissions = new LinkedHashSet<>(); + permissions.add(permission1); + permissions.add(permission2); + + role.setPermissions(permissions); + Assert.assertEquals(2, role.getPermissions().size()); + Assert.assertTrue(role.getPermissions().contains(permission1)); + Assert.assertTrue(role.getPermissions().contains(permission2)); + } + + @Test + public void testAddPermissions() { + Role role = new Role(); + Permission permission1 = new Permission(); + permission1.setName("Permission1"); + + Permission permission2 = new Permission(); + permission2.setName("Permission2"); + + boolean added = role.addPermissions(permission1, permission2); + Assert.assertTrue(added); + Assert.assertEquals(2, role.getPermissions().size()); + Assert.assertTrue(role.getPermissions().contains(permission1)); + Assert.assertTrue(role.getPermissions().contains(permission2)); + } + + @Test + public void testAddPermissionsWithExistingPermissions() { + Role role = new Role(); + Permission permission1 = new Permission(); + permission1.setName("Permission1"); + + role.addPermissions(permission1); + + Permission permission2 = new Permission(); + permission2.setName("Permission2"); + + boolean added = role.addPermissions(permission2); + Assert.assertTrue(added); + Assert.assertEquals(2, role.getPermissions().size()); + Assert.assertTrue(role.getPermissions().contains(permission1)); + Assert.assertTrue(role.getPermissions().contains(permission2)); + } + + @Test + public void testGetAndSetUuid() { + Role role = new Role(); + UUID uuid = UUID.randomUUID(); + role.setUuid(uuid); + Assert.assertEquals(uuid, role.getUuid()); + } + + @Test + public void testToString() { + Role role = new Role(); + role.setName("Test Role"); + role.setUuid(UUID.fromString("123e4567-e89b-12d3-a456-426614174000")); + + Permission permission1 = new Permission(); + permission1.setName("Permission1"); + + Permission permission2 = new Permission(); + permission2.setName("Permission2"); + + role.addPermissions(permission1, permission2); + + String expected = "Role{uuid='123e4567-e89b-12d3-a456-426614174000', name='Test Role', permissions=[Permission1, Permission2]}"; + Assert.assertEquals(expected, role.toString()); + } +} diff --git a/apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java b/apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java new file mode 100644 index 0000000000..6fef0d6675 --- /dev/null +++ b/apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java @@ -0,0 +1,112 @@ +/* + * This file is part of Dependency-Track. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) OWASP Foundation. All Rights Reserved. + */ + +package org.dependencytrack.model; + +import java.util.ArrayList; + +import org.dependencytrack.PersistenceCapableTest; +import org.junit.Assert; +import org.junit.Test; + +import alpine.model.ManagedUser; +import alpine.model.Permission; + +public class UserProjectRoleTest extends PersistenceCapableTest { + + @Test + public void testDefaultConstructor() { + UserProjectRole userProjectRole = new UserProjectRole(); + Assert.assertNull(userProjectRole.getUser()); + Assert.assertNull(userProjectRole.getProject()); + Assert.assertNull(userProjectRole.getRole()); + Assert.assertEquals(0, userProjectRole.getId()); + } + + @Test + public void testParameterizedConstructor() { + final ManagedUser user = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); + final Role role = qm.createRole("maintainer", new ArrayList()); + + final Project project = qm.createProject("test-project-1", "Test Description 1", "1.0.0", null, null, + null, + null, false, false); + + UserProjectRole userProjectRole = new UserProjectRole(user, project, role); + + Assert.assertEquals(user, userProjectRole.getUser()); + Assert.assertEquals(project, userProjectRole.getProject()); + Assert.assertEquals(role, userProjectRole.getRole()); + } + + @Test + public void testGetAndSetId() { + UserProjectRole userProjectRole = new UserProjectRole(); + userProjectRole.setId(123L); + Assert.assertEquals(123L, userProjectRole.getId()); + } + + @Test + public void testGetAndSetUser() { + final ManagedUser user = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); + + UserProjectRole userProjectRole = new UserProjectRole(); + userProjectRole.setUser(user); + + Assert.assertEquals(user, userProjectRole.getUser()); + } + + @Test + public void testGetAndSetProject() { + Project project = new Project(); + project.setName("test-project"); + + UserProjectRole userProjectRole = new UserProjectRole(); + userProjectRole.setProject(project); + + Assert.assertEquals(project, userProjectRole.getProject()); + } + + @Test + public void testGetAndSetRole() { + Role role = new Role(); + role.setName("test-role"); + + UserProjectRole userProjectRole = new UserProjectRole(); + userProjectRole.setRole(role); + + Assert.assertEquals(role, userProjectRole.getRole()); + } + + @Test + public void testToString() { + final ManagedUser user = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); + + Project project = new Project(); + project.setName("test-project"); + + Role role = new Role(); + role.setName("test-role"); + + UserProjectRole userProjectRole = new UserProjectRole(user, project, role); + + String expected = "UserProjectRole{user=test-user, project=test-project, role=test-role}"; + Assert.assertEquals(expected, userProjectRole.toString()); + } +} diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/QueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/QueryManagerTest.java index 0c7a17780d..e5ff2fed00 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/QueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/QueryManagerTest.java @@ -21,7 +21,6 @@ import alpine.model.Permission; import alpine.model.Team; import alpine.model.User; -import alpine.server.auth.PasswordService; import org.dependencytrack.PersistenceCapableTest; import org.dependencytrack.auth.Permissions; import org.dependencytrack.model.Project; @@ -100,7 +99,7 @@ public void tryAcquireAdvisoryLockShouldThrowWhenNoActiveTransaction() { public void testGetEffectivePermissions() { var ldapUser = qm.createLdapUser("ldapuser"); var mgdUser = qm.createManagedUser("mgduser", "mgduser", "mgduser@localhost", - new String(PasswordService.createHash("mgduser".toCharArray())), true, false, false); + TEST_PASSWORD_HASH, true, false, false); var oidcUser = qm.createOidcUser("oidcuser"); BiFunction, Team> teamCreator = (name, permissions) -> { diff --git a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java index 12a046ce2e..b536150fea 100644 --- a/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java +++ b/apiserver/src/test/java/org/dependencytrack/persistence/RoleQueryManagerTest.java @@ -24,7 +24,6 @@ import alpine.model.ManagedUser; import alpine.model.Permission; -import alpine.server.auth.PasswordService; import java.text.ParseException; import java.util.ArrayList; @@ -32,29 +31,35 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.UUID; import org.dependencytrack.PersistenceCapableTest; import org.junit.Assert; import org.junit.Test; -import static org.assertj.core.api.Assertions.assertThat; - public class RoleQueryManagerTest extends PersistenceCapableTest { - private static final String TEST_ROLE_PASSWORD_HASH = new String( - PasswordService.createHash("testuser".toCharArray())); - @Test - public void testCreateRole() { - final Permission readPermission = qm.createPermission("read", "permission to read"); - final Permission writePermission = qm.createPermission("write", "permission to write"); - - List expectedPermissionsList = Arrays.asList( - readPermission, - writePermission); + public void testCreateRoleWithEmptyPermissions() { + Role role = qm.createRole("empty-role", new ArrayList<>()); + Assert.assertNotNull(role); + Assert.assertEquals("empty-role", role.getName()); + Assert.assertTrue(role.getPermissions().isEmpty()); + } - assertThat(qm.createRole("maintainer", expectedPermissionsList)).satisfies( - roleCreated -> assertThat(roleCreated.getName()).isEqualTo("maintainer")); + @Test + public void testCreateRoleWithPermissions() { + Permission readPermission = qm.createPermission("read", "permission to read"); + Permission writePermission = qm.createPermission("write", "permission to write"); + + List permissions = Arrays.asList(readPermission, writePermission); + Role role = qm.createRole("role-with-permissions", permissions); + + Assert.assertNotNull(role); + Assert.assertEquals("role-with-permissions", role.getName()); + Assert.assertEquals(2, role.getPermissions().size()); + Assert.assertTrue(role.getPermissions().contains(readPermission)); + Assert.assertTrue(role.getPermissions().contains(writePermission)); } @Test @@ -74,22 +79,62 @@ public void testGetRoles() { } @Test - public void testGetRole() { - final Role wrongRole = qm.createRole("maintainer", new ArrayList()); - final Role expectedRole = qm.createRole("owner", new ArrayList()); + public void testGetRolesReturnsEmptyList() { + List roles = qm.getRoles(); + Assert.assertNotNull(roles); + Assert.assertTrue(roles.isEmpty()); + } - String expectedRoleUuid = expectedRole.getUuid().toString(); + @Test + public void testGetRoleByUuid() { + Role role = qm.createRole("test-role", new ArrayList<>()); + String uuid = role.getUuid().toString(); - Role actualRole = qm.getRole(expectedRoleUuid); + Role fetchedRole = qm.getRole(uuid); + Assert.assertNotNull(fetchedRole); + Assert.assertEquals(role, fetchedRole); + } - Assert.assertEquals(expectedRole, actualRole); + @Test + public void testGetRoleByUuidNotFound() { + UUID nonExistentUuid = UUID.randomUUID(); + Role fetchedRole = qm.getRole(nonExistentUuid.toString()); + Assert.assertNull(fetchedRole); + } + + @Test + public void testAddRoleToUser() throws ParseException { + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + + qm.addRoleToUser(testUser, maintainerRole, testProject); + + Assert.assertEquals( + qm.getRoles().size(), + 1); + Assert.assertEquals( + qm.getRoles().get(0).getName(), + maintainerRole.getName()); + } + + @Test + public void testRemoveRoleFromUser() throws ParseException { + final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, + null, false, false); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + + qm.addRoleToUser(testUser, maintainerRole, testProject); + Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); } @Test public void testGetUserRoles() throws ParseException { final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, null, false, false); - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); final Role expectedRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(testUser, expectedRole, testProject); @@ -102,7 +147,7 @@ public void testGetUserRoles() throws ParseException { @Test public void testGetUnassignedProjects() throws ParseException { - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); final Project unassignedProject1 = qm.createProject("test-project-1", "Test Description 1", "1.0.0", null, null, @@ -132,6 +177,16 @@ public void testGetUnassignedProjects() throws ParseException { } } + @Test + public void testUpdateRole() { + + final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); + + Role actualRole = qm.updateRole(maintainerRole); + + Assert.assertEquals(maintainerRole, actualRole); + } + @Test public void testGetUnassignedRolePermissions() throws ParseException { final Permission readPermission = qm.createPermission("read", "permission to read"); @@ -149,7 +204,7 @@ public void testGetUnassignedRolePermissions() throws ParseException { final Role assistantRegionalManagerRole = qm.createRole("maintainer", allPermissions.stream().toList()); - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); + final ManagedUser testUser = qm.createManagedUser("test-user", TEST_PASSWORD_HASH); testUser.setPermissions(expectedPermissionsList); qm.persist(testUser); @@ -159,42 +214,4 @@ public void testGetUnassignedRolePermissions() throws ParseException { Assert.assertEquals(expectedPermissionsList.get(0), actualPermissions.get(0)); } - @Test - public void testUpdateRole() { - - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); - - Role actualRole = qm.updateRole(maintainerRole); - - Assert.assertEquals(maintainerRole, actualRole); - } - - @Test - public void testAddRoleToUser() throws ParseException { - final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, - null, false, false); - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); - - qm.addRoleToUser(testUser, maintainerRole, testProject); - - Assert.assertEquals( - qm.getRoles().size(), - 1); - Assert.assertEquals( - qm.getRoles().get(0).getName(), - maintainerRole.getName()); - } - - @Test - public void testRemoveRoleFromUser() throws ParseException { - final Project testProject = qm.createProject("test-project", "Test Description", "1.0.0", null, null, null, - null, false, false); - final ManagedUser testUser = qm.createManagedUser("test-user", TEST_ROLE_PASSWORD_HASH); - final Role maintainerRole = qm.createRole("maintainer", new ArrayList()); - - qm.addRoleToUser(testUser, maintainerRole, testProject); - Assert.assertTrue(qm.removeRoleFromUser(testUser, maintainerRole, testProject)); - } - } diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java index 0f924027f8..6ace35c6d4 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/RoleResourceTest.java @@ -24,10 +24,10 @@ import java.util.UUID; import org.dependencytrack.JerseyTestRule; -import org.dependencytrack.model.Project; -import org.dependencytrack.model.Role; import org.dependencytrack.ResourceTest; import org.dependencytrack.auth.Permissions; +import org.dependencytrack.model.Project; +import org.dependencytrack.model.Role; import org.dependencytrack.persistence.DefaultObjectGenerator; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; @@ -119,10 +119,34 @@ public void createRoleTest() { Assert.assertTrue(UuidUtil.isValidUUID(json.getString("uuid"))); } + @Test + public void testCreateRoleAlreadyExists() { + initializeWithPermissions(Permissions.ACCESS_MANAGEMENT_CREATE); + + Response response = jersey.target(V1_ROLE).request() + .header(X_API_KEY, apiKey) + .put(Entity.json(/* language=JSON */ """ + { + "name": "ABC", + "permissions": [] + } + """)); + Assert.assertEquals(201, response.getStatus()); + + Response secondResponse = jersey.target(V1_ROLE).request() + .header(X_API_KEY, apiKey) + .put(Entity.json(/* language=JSON */ """ + { + "name": "ABC", + "permissions": [] + } + """)); + Assert.assertEquals(409, secondResponse.getStatus()); + } + @Test public void updateRoleTest() { - List rolePermissions = new ArrayList(); - Role role = qm.createRole("My Role", rolePermissions); + Role role = qm.createRole("My Role", new ArrayList()); role.setName("My New Role Name"); Response response = jersey.target(V1_ROLE).request() .header(X_API_KEY, apiKey) @@ -133,10 +157,19 @@ public void updateRoleTest() { Assert.assertEquals("My New Role Name", json.getString("name")); } + @Test + public void testUpdateRoleNotFound() { + Role role = new Role(); + role.setName("My New Role Name"); + Response response = jersey.target(V1_ROLE).request() + .header(X_API_KEY, apiKey) + .post(Entity.entity(role, MediaType.APPLICATION_JSON)); + Assert.assertEquals(404, response.getStatus(), 0); + } + @Test public void deleteRoleTest() { - List rolePermissions = new ArrayList(); - Role role = qm.createRole("My Role", rolePermissions); + Role role = qm.createRole("My Role", new ArrayList()); Response response = jersey.target(V1_ROLE + "/" + role.getUuid()).request() .header(X_API_KEY, apiKey) .method("DELETE"); @@ -144,15 +177,23 @@ public void deleteRoleTest() { Assert.assertEquals(204, response.getStatus(), 0); } + @Test + public void testDeleteRoleNotFound() { + UUID uuid = UUID.randomUUID(); + Response response = jersey.target(V1_ROLE + "/" + uuid).request() + .header(X_API_KEY, apiKey) + .method("DELETE"); + // Hack: Workaround to https://github.com/eclipse-ee4j/jersey/issues/3798 + Assert.assertEquals(404, response.getStatus(), 0); + } + @Test public void getUserRolesTest() throws ParseException { final Project testProject = qm.createProject("Test Project", "Test Description", "1.0.0", null, null, null, null, false, false); ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); - final Role expectedRole = new Role(); - expectedRole.setName("maintainer"); - qm.persist(expectedRole); + final Role expectedRole = qm.createRole("maintainer", new ArrayList()); qm.addRoleToUser(user, expectedRole, testProject); @@ -168,4 +209,19 @@ public void getUserRolesTest() throws ParseException { Assert.assertEquals("maintainer", json.getJsonObject(0).getJsonObject("role").getString("name")); } + @Test + public void testGetUserRolesNoRolesFound() { + ManagedUser user = qm.createManagedUser("roleuser3", TEST_USER_PASSWORD_HASH); + + Response response = jersey.target(V1_ROLE + "/" + user.getUsername() + "/role").request() + .header(X_API_KEY, apiKey) + .get(Response.class); + + Assert.assertEquals(200, response.getStatus(), 0); + + JsonArray json = parseJsonArray(response); + Assert.assertNotNull(json); + Assert.assertEquals(0, json.size()); + } + } From 63f16907d51717e6b32b35d848266999c1cc4c11 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Sat, 31 May 2025 23:53:06 -0600 Subject: [PATCH 38/45] tests: add additional unit test coverage Signed-off-by: Allen Shearin --- .../java/org/dependencytrack/model/Role.java | 5 +- .../model/UserProjectRole.java | 2 +- .../resources/v1/UserResource.java | 133 +++++++++--------- .../model/UserProjectRoleTest.java | 2 +- .../v1/AccessControlResourceTest.java | 59 +++++++- .../resources/v1/PermissionResourceTest.java | 114 +++++++++++++++ 6 files changed, 240 insertions(+), 75 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/model/Role.java b/apiserver/src/main/java/org/dependencytrack/model/Role.java index 31e69d07a9..90efc9c4c6 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/Role.java +++ b/apiserver/src/main/java/org/dependencytrack/model/Role.java @@ -32,11 +32,12 @@ import jakarta.validation.constraints.Size; import java.io.Serializable; - +import java.util.Comparator; import java.util.LinkedHashSet; import java.util.Objects; import java.util.Set; import java.util.UUID; +import java.util.function.Function; import javax.jdo.annotations.Column; import javax.jdo.annotations.Element; @@ -139,8 +140,8 @@ public void setUuid(UUID uuid) { @Override public String toString() { var permissionStrings = permissions.stream() - .sorted((p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName())) .map(Permission::getName) + .sorted(Comparator.comparing(Function.identity(), String.CASE_INSENSITIVE_ORDER)) .toList(); return "%s{uuid='%s', name='%s', permissions=%s}".formatted( diff --git a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java index e01aa74a0e..6d77abf223 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java @@ -102,7 +102,7 @@ public void setRole(final Role role) { @Override public String toString() { - return "%s{user=%s, project=%s, role=%s}".formatted( + return "%s{user='%s', project='%s', role='%s'}".formatted( getClass().getSimpleName(), user.getUsername(), project.getName(), role.getName()); } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 127d06478f..dcfb44b2eb 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -170,7 +170,7 @@ public Response validateCredentials(@FormParam("username") String username, @For @AuthenticationNotRequired public Response validateOidcAccessToken(@Parameter(description = "An OAuth2 access token", required = true) @FormParam("idToken") final String idToken, - @FormParam("accessToken") final String accessToken) { + @FormParam("accessToken") final String accessToken) { final OidcAuthenticationService authService = new OidcAuthenticationService(idToken, accessToken); if (!authService.isSpecified()) { @@ -827,6 +827,72 @@ public Response setUserTeams( } } + @PUT + @Path("/{username}/membership") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(summary = "Adds the username to the specified team.", description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "The updated user", content = @Content(schema = @Schema(implementation = User.class))), + @ApiResponse(responseCode = "304", description = "The user is already a member of the specified team(s)"), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "The user or team(s) could not be found") + }) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) + public Response setUserTeams( + @Parameter(description = "A valid username", required = true) @PathParam("username") String username, + @Parameter(description = "The UUID(s) of the team(s) to associate username with", required = true) @Valid TeamsSetRequest request) { + try (QueryManager qm = new QueryManager()) { + User user = qm.getUser(username); + if (user == null) + return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); + + // Compare given team uuids against current user teams + final Set currentUserTeams = user.getTeams() == null ? Collections.emptySet() + : user.getTeams().stream() + .map(Team::getUuid) + .map(UUID::toString) + .collect(Collectors.toSet()); + + if (currentUserTeams.equals(request.teams())) + return Response.notModified().entity("The user is already a member of the selected team(s)").build(); + + final Query query = qm.getPersistenceManager().newQuery(Team.class) + .filter(":uuids.contains(uuid)") + .setNamedParameters(Map.of("uuids", request.teams())); + + final List requestedTeams; + + try { + requestedTeams = query.executeList(); + } finally { + query.closeAll(); + } + + // Check that all requested teams exist + List notFound = requestedTeams.stream() + .map(Team::getName) + .filter(name -> !request.teams().contains(name)) + .toList(); + + if (notFound.size() > 0) { + Map response = new HashMap<>(); + response.put("error", "One or more teams could not be found"); + response.put("teams", notFound); + + return Response.status(Response.Status.BAD_REQUEST).entity(response).build(); + } + + user.setTeams(requestedTeams); + qm.persist(user); + + super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added team membership for: %s / team: %s" + .formatted(user.getUsername(), requestedTeams.toString())); + + return Response.ok(user).build(); + } + } + private void dispatchUserCreatedNotification(final String content, final UserSubject subject) { eventDispatcher.dispatchNotification(new Notification() .scope(NotificationScope.SYSTEM) @@ -947,69 +1013,4 @@ public Response removeProjectRoleFromUser( } } - @PUT - @Path("/{username}/membership") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(summary = "Adds the username to the specified team.", description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "The updated user", content = @Content(schema = @Schema(implementation = User.class))), - @ApiResponse(responseCode = "304", description = "The user is already a member of the specified team(s)"), - @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse(responseCode = "404", description = "The user or team(s) could not be found") - }) - @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) - public Response setUserTeams( - @Parameter(description = "A valid username", required = true) @PathParam("username") String username, - @Parameter(description = "The UUID(s) of the team(s) to associate username with", required = true) @Valid TeamsSetRequest request) { - try (QueryManager qm = new QueryManager()) { - User user = qm.getUser(username); - if (user == null) - return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); - - // Compare given team uuids against current user teams - final Set currentUserTeams = user.getTeams() == null ? Collections.emptySet() - : user.getTeams().stream() - .map(Team::getUuid) - .map(UUID::toString) - .collect(Collectors.toSet()); - - if (currentUserTeams.equals(request.teams())) - return Response.notModified().entity("The user is already a member of the selected team(s)").build(); - - final Query query = qm.getPersistenceManager().newQuery(Team.class) - .filter(":uuids.contains(uuid)") - .setNamedParameters(Map.of("uuids", request.teams())); - - final List requestedTeams; - - try { - requestedTeams = query.executeList(); - } finally { - query.closeAll(); - } - - // Check that all requested teams exist - List notFound = requestedTeams.stream() - .map(Team::getName) - .filter(name -> !request.teams().contains(name)) - .toList(); - - if (notFound.size() > 0) { - Map response = new HashMap<>(); - response.put("error", "One or more teams could not be found"); - response.put("teams", notFound); - - return Response.status(Response.Status.BAD_REQUEST).entity(response).build(); - } - - user.setTeams(requestedTeams); - qm.persist(user); - - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added team membership for: %s / team: %s" - .formatted(user.getUsername(), requestedTeams.toString())); - - return Response.ok(user).build(); - } - } } diff --git a/apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java b/apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java index 6fef0d6675..00274528a9 100644 --- a/apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java +++ b/apiserver/src/test/java/org/dependencytrack/model/UserProjectRoleTest.java @@ -106,7 +106,7 @@ public void testToString() { UserProjectRole userProjectRole = new UserProjectRole(user, project, role); - String expected = "UserProjectRole{user=test-user, project=test-project, role=test-role}"; + String expected = "UserProjectRole{user='test-user', project='test-project', role='test-role'}"; Assert.assertEquals(expected, userProjectRole.toString()); } } diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java index 54dfefd3ae..b6fce6ab00 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java @@ -18,7 +18,9 @@ */ package org.dependencytrack.resources.v1; +import alpine.model.ManagedUser; import alpine.model.Team; +import alpine.server.auth.PasswordService; import alpine.server.filters.ApiFilter; import alpine.server.filters.AuthenticationFilter; import alpine.server.filters.AuthorizationFilter; @@ -38,6 +40,9 @@ public class AccessControlResourceTest extends ResourceTest { + protected static final String TEST_PASSWORD_HASH = new String( + PasswordService.createHash("testuser".toCharArray())); + @ClassRule public static JerseyTestRule jersey = new JerseyTestRule( new ResourceConfig(AccessControlResource.class) @@ -162,7 +167,8 @@ public void deleteMappingTest() { project.addAccessTeam(otherTeam); qm.persist(project); - final Response response = jersey.target(V1_ACL + "/mapping/team/" + otherTeam.getUuid() + "/project/" + project.getUuid()) + final Response response = jersey + .target(V1_ACL + "/mapping/team/" + otherTeam.getUuid() + "/project/" + project.getUuid()) .request() .header(X_API_KEY, apiKey) .delete(); @@ -170,7 +176,8 @@ public void deleteMappingTest() { qm.getPersistenceManager().evictAll(); - assertThat(project.getAccessTeams()).satisfiesExactly(team -> assertThat(team.getId()).isEqualTo(super.team.getId())); + assertThat(project.getAccessTeams()) + .satisfiesExactly(team -> assertThat(team.getId()).isEqualTo(super.team.getId())); } @Test @@ -182,7 +189,8 @@ public void deleteMappingTeamNotFoundTest() { project.addAccessTeam(super.team); qm.persist(project); - final Response response = jersey.target(V1_ACL + "/mapping/team/c4e2c34b-38c5-4b47-991f-b207ff71bfeb/project/" + project.getUuid()) + final Response response = jersey + .target(V1_ACL + "/mapping/team/c4e2c34b-38c5-4b47-991f-b207ff71bfeb/project/" + project.getUuid()) .request() .header(X_API_KEY, apiKey) .delete(); @@ -205,7 +213,9 @@ public void deleteMappingProjectNotFoundTest() { project.addAccessTeam(super.team); qm.persist(project); - final Response response = jersey.target(V1_ACL + "/mapping/team/" + super.team.getUuid() + "/project/c4e2c34b-38c5-4b47-991f-b207ff71bfeb") + final Response response = jersey + .target(V1_ACL + "/mapping/team/" + super.team.getUuid() + + "/project/c4e2c34b-38c5-4b47-991f-b207ff71bfeb") .request() .header(X_API_KEY, apiKey) .delete(); @@ -219,4 +229,43 @@ public void deleteMappingProjectNotFoundTest() { """); } -} \ No newline at end of file + @Test + public void retrieveUserProjectsTest() { + initializeWithPermissions(Permissions.ACCESS_MANAGEMENT_READ); + + final var project1 = new Project(); + project1.setName("Project 1"); + qm.persist(project1); + + final var project2 = new Project(); + project2.setName("Project 2"); + qm.persist(project2); + + final ManagedUser user = qm.createManagedUser("user", TEST_PASSWORD_HASH); + + final Response response = jersey.target(V1_ACL + "/user/" + user.getUsername()) + .request() + .header(X_API_KEY, apiKey) + .get(); + + assertThat(response.getStatus()).isEqualTo(200); + assertThatJson(getPlainTextBody(response)).isArray().extracting("name").containsExactly("Project 1", + "Project 2"); + } + + @Test + public void retrieveUserProjectsNoContentTest() { + initializeWithPermissions(Permissions.ACCESS_MANAGEMENT_READ); + + final ManagedUser user = qm.createManagedUser("user", TEST_PASSWORD_HASH); + + final Response response = jersey.target(V1_ACL + "/user/" + user.getUsername()) + .request() + .header(X_API_KEY, apiKey) + .get(); + + assertThat(response.getStatus()).isEqualTo(204); + assertThat(response.hasEntity()).isFalse(); + } + +} diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java index 9677001edb..adcafe3621 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java @@ -26,6 +26,7 @@ import org.dependencytrack.JerseyTestRule; import org.dependencytrack.ResourceTest; import org.dependencytrack.auth.Permissions; +import org.dependencytrack.model.Role; import org.dependencytrack.persistence.DefaultObjectGenerator; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; @@ -39,6 +40,8 @@ import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; + +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -447,6 +450,117 @@ public void setTeamPermissionsTest() { Collections.disjoint(userPermissions, permissionSet1)); Assert.assertTrue("User should have all new permissions assigned: " + userPermissions, userPermissions.containsAll(permissionSet2)); + } + + @Test + public void addPermissionToRoleTest() { + Role role = qm.createRole("Test Role", new ArrayList()); + + Response response = jersey.target(V1_PERMISSION + "/PORTFOLIO_MANAGEMENT/role/" + role.getUuid()).request() + .header(X_API_KEY, apiKey) + .post(Entity.entity(null, MediaType.APPLICATION_JSON)); + + Assert.assertEquals(200, response.getStatus(), 0); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("Test Role", json.getString("name")); + Assert.assertEquals(1, json.getJsonArray("permissions").size()); + Assert.assertEquals("PORTFOLIO_MANAGEMENT", + json.getJsonArray("permissions").getJsonObject(0).getString("name")); + } + + @Test + public void addPermissionToRoleInvalidRoleTest() { + Response response = jersey.target(V1_PERMISSION + "/PORTFOLIO_MANAGEMENT/role/" + UUID.randomUUID()).request() + .header(X_API_KEY, apiKey) + .post(Entity.entity(null, MediaType.APPLICATION_JSON)); + + Assert.assertEquals(404, response.getStatus(), 0); + Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); + String body = getPlainTextBody(response); + Assert.assertEquals("The role could not be found.", body); + } + + @Test + public void addPermissionToRoleInvalidPermissionTest() { + Role role = qm.createRole("Test Role", new ArrayList()); + + Response response = jersey.target(V1_PERMISSION + "/BLAH/role/" + role.getUuid()).request() + .header(X_API_KEY, apiKey) + .post(Entity.entity(null, MediaType.APPLICATION_JSON)); + + Assert.assertEquals(404, response.getStatus(), 0); + Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); + String body = getPlainTextBody(response); + Assert.assertEquals("The permission could not be found.", body); + } + + @Test + public void addPermissionToRoleDuplicateTest() { + List permissionSet1 = List.of( + qm.getPermission("PORTFOLIO_MANAGEMENT")); + Role role = qm.createRole("Test Role", permissionSet1); + + Response response = jersey.target(V1_PERMISSION + "/PORTFOLIO_MANAGEMENT/role/" + role.getUuid()).request() + .header(X_API_KEY, apiKey) + .post(Entity.entity(null, MediaType.APPLICATION_JSON)); + + Assert.assertEquals(304, response.getStatus(), 0); + Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); + } + + @Test + public void removePermissionFromRoleTest() { + List permissionSet1 = List.of( + qm.getPermission("PORTFOLIO_MANAGEMENT")); + Role role = qm.createRole("Test Role", permissionSet1); + Response response = jersey.target(V1_PERMISSION + "/PORTFOLIO_MANAGEMENT/role/" + role.getUuid()).request() + .header(X_API_KEY, apiKey) + .delete(); + + Assert.assertEquals(200, response.getStatus(), 0); + JsonObject json = parseJsonObject(response); + Assert.assertNotNull(json); + Assert.assertEquals("Test Role", json.getString("name")); + Assert.assertEquals(0, json.getJsonArray("permissions").size()); + } + + @Test + public void removePermissionFromRoleInvalidRoleTest() { + Response response = jersey.target(V1_PERMISSION + "/PORTFOLIO_MANAGEMENT/role/" + UUID.randomUUID()).request() + .header(X_API_KEY, apiKey) + .delete(); + + Assert.assertEquals(404, response.getStatus(), 0); + Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); + String body = getPlainTextBody(response); + Assert.assertEquals("The role could not be found.", body); + } + + @Test + public void removePermissionFromRoleInvalidPermissionTest() { + Role role = qm.createRole("Test Role", new ArrayList()); + + Response response = jersey.target(V1_PERMISSION + "/BLAH/role/" + role.getUuid()).request() + .header(X_API_KEY, apiKey) + .delete(); + + Assert.assertEquals(404, response.getStatus(), 0); + Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); + String body = getPlainTextBody(response); + Assert.assertEquals("The permission could not be found.", body); + } + + @Test + public void removePermissionFromRoleNoChangesTest() { + Role role = qm.createRole("Test Role", new ArrayList()); + + Response response = jersey.target(V1_PERMISSION + "/PORTFOLIO_MANAGEMENT/role/" + role.getUuid()).request() + .header(X_API_KEY, apiKey) + .delete(); + + Assert.assertEquals(304, response.getStatus(), 0); + Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); } } From eda79ac173fab80351c59067806c86af0b0a44a7 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Sun, 1 Jun 2025 11:32:24 -0600 Subject: [PATCH 39/45] chore: cleanup merge duplication Signed-off-by: Allen Shearin --- .../resources/v1/UserResource.java | 66 ------------------- 1 file changed, 66 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index dcfb44b2eb..5962502fa9 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -827,72 +827,6 @@ public Response setUserTeams( } } - @PUT - @Path("/{username}/membership") - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Operation(summary = "Adds the username to the specified team.", description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "The updated user", content = @Content(schema = @Schema(implementation = User.class))), - @ApiResponse(responseCode = "304", description = "The user is already a member of the specified team(s)"), - @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse(responseCode = "404", description = "The user or team(s) could not be found") - }) - @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE }) - public Response setUserTeams( - @Parameter(description = "A valid username", required = true) @PathParam("username") String username, - @Parameter(description = "The UUID(s) of the team(s) to associate username with", required = true) @Valid TeamsSetRequest request) { - try (QueryManager qm = new QueryManager()) { - User user = qm.getUser(username); - if (user == null) - return Response.status(Response.Status.NOT_FOUND).entity("The user could not be found.").build(); - - // Compare given team uuids against current user teams - final Set currentUserTeams = user.getTeams() == null ? Collections.emptySet() - : user.getTeams().stream() - .map(Team::getUuid) - .map(UUID::toString) - .collect(Collectors.toSet()); - - if (currentUserTeams.equals(request.teams())) - return Response.notModified().entity("The user is already a member of the selected team(s)").build(); - - final Query query = qm.getPersistenceManager().newQuery(Team.class) - .filter(":uuids.contains(uuid)") - .setNamedParameters(Map.of("uuids", request.teams())); - - final List requestedTeams; - - try { - requestedTeams = query.executeList(); - } finally { - query.closeAll(); - } - - // Check that all requested teams exist - List notFound = requestedTeams.stream() - .map(Team::getName) - .filter(name -> !request.teams().contains(name)) - .toList(); - - if (notFound.size() > 0) { - Map response = new HashMap<>(); - response.put("error", "One or more teams could not be found"); - response.put("teams", notFound); - - return Response.status(Response.Status.BAD_REQUEST).entity(response).build(); - } - - user.setTeams(requestedTeams); - qm.persist(user); - - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Added team membership for: %s / team: %s" - .formatted(user.getUsername(), requestedTeams.toString())); - - return Response.ok(user).build(); - } - } - private void dispatchUserCreatedNotification(final String content, final UserSubject subject) { eventDispatcher.dispatchNotification(new Notification() .scope(NotificationScope.SYSTEM) From 12e8d762dd258a996a3baa7f43de4c254c359a9e Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Sun, 1 Jun 2025 16:16:49 -0600 Subject: [PATCH 40/45] chore: remove unused imports Signed-off-by: Allen Shearin --- .../java/org/dependencytrack/resources/v1/UserResource.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 5962502fa9..13a6ddeca1 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -80,15 +80,12 @@ import javax.jdo.Query; import java.security.Principal; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; /** * JAX-RS resources for processing users. From 237b9c7e138845cdafdfafc321028b22745244cc Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Mon, 2 Jun 2025 08:33:45 -0600 Subject: [PATCH 41/45] chore: address PR comments - Deleted ununsed ProejctRowMapper class - AccessControlResource response tweak, associated test updates - log cleanup Signed-off-by: Allen Shearin --- .../jdbi/mapping/ProjectRowMapper.java | 88 ------------------- .../resources/v1/AccessControlResource.java | 2 +- .../resources/v1/RoleResource.java | 2 +- .../v1/AccessControlResourceTest.java | 6 +- 4 files changed, 7 insertions(+), 91 deletions(-) delete mode 100644 apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java b/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java deleted file mode 100644 index ba435afed2..0000000000 --- a/apiserver/src/main/java/org/dependencytrack/persistence/jdbi/mapping/ProjectRowMapper.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.persistence.jdbi.mapping; - -import org.cyclonedx.model.ExternalReference; -import org.dependencytrack.model.Classifier; -import org.dependencytrack.model.Project; -import org.dependencytrack.persistence.converter.OrganizationalContactsJsonConverter; -import org.dependencytrack.persistence.converter.OrganizationalEntityJsonConverter; -import org.jdbi.v3.core.mapper.RowMapper; -import org.jdbi.v3.core.statement.StatementContext; - -import com.fasterxml.jackson.core.type.TypeReference; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; -import java.util.UUID; - -import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.deserializeJson; -import static org.dependencytrack.persistence.jdbi.mapping.RowMapperUtil.maybeSet; - -public class ProjectRowMapper implements RowMapper { - - private static final TypeReference> EXTERNAL_REFS_TYPE_REF = new TypeReference<>() { - }; - - @Override - public Project map(final ResultSet rs, final StatementContext ctx) throws SQLException { - final var project = new Project(); - - maybeSet(rs, "ID", ResultSet::getLong, project::setId); - maybeSet(rs, "CLASSIFIER", ResultSet::getString, Classifier::valueOf); - maybeSet(rs, "CPE", ResultSet::getString, project::setCpe); - maybeSet(rs, "DESCRIPTION", ResultSet::getString, project::setDescription); - maybeSet(rs, "DIRECT_DEPENDENCIES", ResultSet::getString, project::setDirectDependencies); - deserializeJson(rs, "EXTERNAL_REFERENCES", EXTERNAL_REFS_TYPE_REF); - maybeSet(rs, "GROUP", ResultSet::getString, project::setGroup); - maybeSet(rs, "LAST_BOM_IMPORTED", ResultSet::getDate, project::setLastBomImport); - maybeSet(rs, "LAST_BOM_IMPORTED_FORMAT", ResultSet::getString, project::setLastBomImportFormat); - maybeSet(rs, "LAST_RISKSCORE", ResultSet::getDouble, project::setLastInheritedRiskScore); - maybeSet(rs, "NAME", ResultSet::getString, project::setName); - maybeSet(rs, "PARENT_PROJECT_ID", ResultSet::getLong, value -> { - var parent = new Project(); - parent.setId(value); - project.setParent(parent); - }); - maybeSet(rs, "PUBLISHER", ResultSet::getString, project::setPublisher); - maybeSet(rs, "PURL", ResultSet::getString, project::setPurl); - maybeSet(rs, "SWIDTAGID", ResultSet::getString, project::setSwidTagId); - maybeSet(rs, "UUID", ResultSet::getString, value -> { - var uuid = UUID.fromString(value); - project.setUuid(uuid); - }); - maybeSet(rs, "VERSION", ResultSet::getString, project::setVersion); - maybeSet(rs, "SUPPLIER", ResultSet::getString, value -> { - var converter = new OrganizationalEntityJsonConverter(); - project.setSupplier(converter.convertToAttribute(value)); - }); - maybeSet(rs, "MANUFACTURER", ResultSet::getString, value -> { - var converter = new OrganizationalEntityJsonConverter(); - project.setManufacturer(converter.convertToAttribute(value)); - }); - maybeSet(rs, "AUTHORS", ResultSet::getString, values -> { - var converter = new OrganizationalContactsJsonConverter(); - project.setAuthors(converter.convertToAttribute(values)); - }); - - return project; - } - -} \ No newline at end of file diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index c2d98db4e4..37076219e7 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -141,7 +141,7 @@ public Response retrieveUserProjects( List projects = qm.getUnassignedProjects(username); if (projects == null || projects.isEmpty()) - return Response.noContent().build(); + return Response.ok("[]").header(TOTAL_COUNT_HEADER, 0).build(); return Response.ok(projects).header(TOTAL_COUNT_HEADER, projects.size()).build(); } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java index 6ed507a6ab..b8133d2267 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/RoleResource.java @@ -232,7 +232,7 @@ public Response getUserRoles( try (QueryManager qm = new QueryManager()) { List roles = qm.getUserRoles(username); if (roles == null || roles.isEmpty()) { - LOGGER.info("No roles found for user: " + username); + LOGGER.debug("No roles found for user: " + username); return Response.ok(List.of()).build(); } diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java index b6fce6ab00..14bd81acbf 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java @@ -249,6 +249,8 @@ public void retrieveUserProjectsTest() { .get(); assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getHeaders().get(TOTAL_COUNT_HEADER)).isNotNull(); + assertThat(response.getHeaders().get(TOTAL_COUNT_HEADER).get(0)).isEqualTo("2"); assertThatJson(getPlainTextBody(response)).isArray().extracting("name").containsExactly("Project 1", "Project 2"); } @@ -264,7 +266,9 @@ public void retrieveUserProjectsNoContentTest() { .header(X_API_KEY, apiKey) .get(); - assertThat(response.getStatus()).isEqualTo(204); + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getHeaders().get(TOTAL_COUNT_HEADER)).isNotNull(); + assertThat(response.getHeaders().get(TOTAL_COUNT_HEADER).get(0)).isEqualTo("0"); assertThat(response.hasEntity()).isFalse(); } From b4006b580f87e774b582425d7220c1c8318066f8 Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Mon, 2 Jun 2025 11:56:59 -0500 Subject: [PATCH 42/45] fix: combine user project effective permissions triggers Signed-off-by: Jonathan Howard --- .../resources/migration/changelog-v5.6.0.xml | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index 622ab3389c..2929841cfb 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -2432,19 +2432,27 @@ -- Helper function to recalculate all user permissions for a project. -- Called by trigger functions to update the values in the USER_PROJECT_EFFECTIVE_PERMISSIONS table. - CREATE OR REPLACE FUNCTION recalc_user_project_role_effective_permissions(project_ids BIGINT[]) + CREATE OR REPLACE FUNCTION recalc_user_project_effective_permissions(project_ids BIGINT[]) RETURNS void AS $$ - DECLARE - tbl_prefix TEXT; BEGIN - -- Remove any existing effective permissions for this project + -- Remove any existing effective permissions for this project. DELETE FROM "USER_PROJECT_EFFECTIVE_PERMISSIONS" WHERE "PROJECT_ID" = ANY(project_ids); - -- Rebuild effective permissions for all users + -- Rebuild effective permissions for users INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" ("USER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") - SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" + SELECT DISTINCT ut."USER_ID", pat."PROJECT_ID", tp."PERMISSION_ID", p."NAME" + FROM "PROJECT_ACCESS_TEAMS" pat + INNER JOIN "TEAMS_PERMISSIONS" tp + ON tp."TEAM_ID" = pat."TEAM_ID" + INNER JOIN "PERMISSION" p + ON p."ID" = tp."PERMISSION_ID" + INNER JOIN "USERS_TEAMS" ut + ON ut."TEAM_ID" = pat."TEAM_ID" + WHERE pat."PROJECT_ID" = ANY(project_ids) + UNION ALL + SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" FROM "USER_PROJECT_ROLES" upr INNER JOIN "ROLES_PERMISSIONS" rp ON rp."ROLE_ID" = upr."ROLE_ID" @@ -2482,7 +2490,7 @@ WHERE "ROLE_ID" = ANY(role_ids); END IF; - PERFORM recalc_user_project_role_effective_permissions(project_ids); + PERFORM recalc_user_project_effective_permissions(project_ids); RETURN NULL; END; $$ LANGUAGE plpgsql; @@ -2515,7 +2523,7 @@ WHERE "ROLE_ID" = ANY(role_ids); END IF; - PERFORM recalc_user_project_role_effective_permissions(project_ids); + PERFORM recalc_user_project_effective_permissions(project_ids); RETURN NULL; END; $$ LANGUAGE plpgsql; @@ -2554,7 +2562,7 @@ WHERE "ROLE_ID" = ANY(role_ids); END IF; - PERFORM recalc_user_project_role_effective_permissions(project_ids); + PERFORM recalc_user_project_effective_permissions(project_ids); RETURN NULL; END; $$ LANGUAGE plpgsql; @@ -2562,21 +2570,21 @@ -- INSERT trigger for USER_PROJECT_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_insert + CREATE TRIGGER trigger_effective_permissions_mx_on_user_project_roles_insert AFTER INSERT ON "USER_PROJECT_ROLES" REFERENCING NEW TABLE AS new_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_insert(); -- DELETE trigger for USER_PROJECT_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_delete + CREATE TRIGGER trigger_effective_permissions_mx_on_user_project_roles_delete AFTER DELETE ON "USER_PROJECT_ROLES" REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION role_effective_permissions_mx_on_delete(); -- UPDATE trigger for USER_PROJECT_ROLES - CREATE TRIGGER trigger_effective_permissions_mx_on_users_roles_update + CREATE TRIGGER trigger_effective_permissions_mx_on_user_project_roles_update AFTER UPDATE ON "USER_PROJECT_ROLES" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT From 4d0d0f087a21649136d1b9ad6eb78865cbd9d017 Mon Sep 17 00:00:00 2001 From: Allen Shearin Date: Mon, 2 Jun 2025 12:32:57 -0600 Subject: [PATCH 43/45] refactor: update addRoleToUser to check for existing role on project Signed-off-by: Allen Shearin --- .../persistence/RoleQueryManager.java | 24 ++++++++++++++----- .../resources/v1/UserResource.java | 4 +--- .../v1/AccessControlResourceTest.java | 1 - 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java index fed17397ce..39d096976c 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/RoleQueryManager.java @@ -155,16 +155,28 @@ public Role updateRole(final Role transientRole) { @Override public boolean addRoleToUser(final User user, final Role role, final Project project) { - Query query = pm.newQuery(UserProjectRole.class) - .filter("user.id == :userId && project.id == :projectId && role.id == :roleId") - .setParameters(user.getId(), project.getId(), role.getId()) - .result("count(this) > 0"); + final Query query = pm.newQuery(UserProjectRole.class) + .filter("user.id == :userId && project.id == :projectId") + .setParameters(user.getId(), project.getId()); - if (executeAndCloseResultUnique(query, Boolean.class)) - return false; + final UserProjectRole existingRole = executeAndCloseUnique(query); + + if (existingRole != null) { + return handleExistingRole(user, role, project, existingRole); + } persist(new UserProjectRole(user, project, role)); + return true; + } + private boolean handleExistingRole(final User user, final Role role, final Project project, final UserProjectRole existingRole) { + if (existingRole.getRole().getId() == role.getId()) { + LOGGER.debug("User '%s' already has role '%s' on project '%s', no action taken.".formatted( + user.getUsername(), role.getName(), project.getName())); + return false; + } + existingRole.setRole(role); + persist(existingRole); return true; } diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 13a6ddeca1..6df7948461 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -885,11 +885,9 @@ public Response assignProjectRoleToUser( "One or more variables could not be found", problems).toResponse(); - if (qm.userProjectRoleExists(user, role, project)) + if (!qm.addRoleToUser(user, role, project)) return Response.notModified().build(); - qm.addRoleToUser(user, role, project); - super.logSecurityEvent(LOGGER, SecurityMarkers.SECURITY_AUDIT, "Granted project role: user='%s', role='%s', project='%s'" .formatted(user.getUsername(), role.getName(), project.getName())); diff --git a/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java b/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java index 14bd81acbf..9cc6678d64 100644 --- a/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java +++ b/apiserver/src/test/java/org/dependencytrack/resources/v1/AccessControlResourceTest.java @@ -269,7 +269,6 @@ public void retrieveUserProjectsNoContentTest() { assertThat(response.getStatus()).isEqualTo(200); assertThat(response.getHeaders().get(TOTAL_COUNT_HEADER)).isNotNull(); assertThat(response.getHeaders().get(TOTAL_COUNT_HEADER).get(0)).isEqualTo("0"); - assertThat(response.hasEntity()).isFalse(); } } From 40d69f59b5f20857e2f757fb341196041e138f5b Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Tue, 3 Jun 2025 16:16:24 -0500 Subject: [PATCH 44/45] refactor: schema suggestions Signed-off-by: Jonathan Howard --- .../java/org/dependencytrack/model/UserProjectRole.java | 2 +- .../src/main/resources/migration/changelog-v5.6.0.xml | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java index 6d77abf223..88c1ccd356 100644 --- a/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java +++ b/apiserver/src/main/java/org/dependencytrack/model/UserProjectRole.java @@ -40,7 +40,7 @@ */ @PersistenceCapable(table = "USER_PROJECT_ROLES") @JsonInclude(JsonInclude.Include.NON_NULL) -@Index(name = "USER_PROJECT_ROLES_IDX", unique = "true", members = { "user", "project", "role" }) +@Index(name = "USER_PROJECT_ROLES_IDX", unique = "true", members = { "user", "project" }) public class UserProjectRole implements Serializable { @PrimaryKey diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index 2929841cfb..a98c459ef7 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -2426,7 +2426,6 @@ - @@ -2442,7 +2441,7 @@ -- Rebuild effective permissions for users INSERT INTO "USER_PROJECT_EFFECTIVE_PERMISSIONS" ("USER_ID", "PROJECT_ID", "PERMISSION_ID", "PERMISSION_NAME") - SELECT DISTINCT ut."USER_ID", pat."PROJECT_ID", tp."PERMISSION_ID", p."NAME" + SELECT ut."USER_ID", pat."PROJECT_ID", tp."PERMISSION_ID", p."NAME" FROM "PROJECT_ACCESS_TEAMS" pat INNER JOIN "TEAMS_PERMISSIONS" tp ON tp."TEAM_ID" = pat."TEAM_ID" @@ -2451,8 +2450,8 @@ INNER JOIN "USERS_TEAMS" ut ON ut."TEAM_ID" = pat."TEAM_ID" WHERE pat."PROJECT_ID" = ANY(project_ids) - UNION ALL - SELECT DISTINCT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" + UNION + SELECT upr."USER_ID", upr."PROJECT_ID", rp."PERMISSION_ID", p."NAME" FROM "USER_PROJECT_ROLES" upr INNER JOIN "ROLES_PERMISSIONS" rp ON rp."ROLE_ID" = upr."ROLE_ID" From 9325a1011e60345709e3d368b3cddde4807f8bef Mon Sep 17 00:00:00 2001 From: Jonathan Howard Date: Wed, 4 Jun 2025 08:06:07 -0500 Subject: [PATCH 45/45] fix: trigger function call Signed-off-by: Jonathan Howard --- .../src/main/resources/migration/changelog-v5.6.0.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml index a98c459ef7..f610455b47 100644 --- a/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml +++ b/persistence-migration/src/main/resources/migration/changelog-v5.6.0.xml @@ -2608,7 +2608,7 @@ AFTER UPDATE ON "ROLES_PERMISSIONS" REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table FOR EACH STATEMENT - EXECUTE FUNCTION effective_permissions_mx_on_update(); + EXECUTE FUNCTION role_effective_permissions_mx_on_update();