frontend icon indicating copy to clipboard operation
frontend copied to clipboard

Display when updated version are available in Dependency Graph

Open Yaytay opened this issue 1 year ago • 4 comments

Current Behavior

On the Components view we have the convenient flag to say when a newer version is available. Most Components are transitive and much as we might like to update them, we don't have any easy way to do so. Nowhere in the UI is there a way to see all the direct dependencies along with a highlight of the ones that we can update.

Proposed Behavior

I can see two ways the UI could be enhanced to provide this information:

  1. Have a flag on the Components view to only show direct dependencies of the project.
  2. Put the version flag onto the Dependency Graph.

I would prefer not to have the green triangle (anywhere - I don't think an OK symbol should ever be a triangle with an exclamation mark in it, and the colours chosen are not helpful for green/yellow colour blindness).

Checklist

Yaytay avatar Jul 07 '23 07:07 Yaytay

@walterdeboer had the same thought and implemented https://github.com/DependencyTrack/dependency-track/pull/2568. It's already merged to master and will be shipped with Dependency-Track v4.9.

You can give it a spin using our snapshot builds of both API server and frontend, and let us know if it fulfills your request!

nscuro avatar Jul 07 '23 08:07 nscuro

The screenshots look great, but unfortunately when I try to run the snapshot image the backed is failing. I don't think this is relevant to that change, but means I can't test it today. The exception is:

2023-07-07 08:20:52,704 ERROR [Datastore] Error thrown executing ALTER TABLE VULNERABILITY ADD COLUMN OWASPRRTECHNICALIMPACTSCORE DECIMAL(19,1) NULL : General error: "java.lang.NullPointerException: Cannot read field ""streamStoreId"" because ""<local11>"" is null"; SQL statement:
INSERT INTO "PUBLIC"."VULNERABILITY_COPY_3_0"("ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR") OVERRIDING SYSTEM VALUE SELECT "ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR" FROM "PUBLIC"."VULNERABILITY" [50000-214]
org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.NullPointerException: Cannot read field ""streamStoreId"" because ""<local11>"" is null"; SQL statement:
INSERT INTO "PUBLIC"."VULNERABILITY_COPY_3_0"("ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR") OVERRIDING SYSTEM VALUE SELECT "ID", "CREATED", "CREDITS", "CVSSV2BASESCORE", "CVSSV2EXPLOITSCORE", "CVSSV2IMPACTSCORE", "CVSSV2VECTOR", "CVSSV3BASESCORE", "CVSSV3EXPLOITSCORE", "CVSSV3IMPACTSCORE", "CVSSV3VECTOR", "CWES", "DESCRIPTION", "DETAIL", "EPSSPERCENTILE", "EPSSSCORE", "FRIENDLYVULNID", "PATCHEDVERSIONS", "PUBLISHED", "RECOMMENDATION", "REFERENCES", "SEVERITY", "SOURCE", "SUBTITLE", "TITLE", "UPDATED", "UUID", "VULNID", "VULNERABLEVERSIONS", "OWASPRRLIKELIHOODSCORE", "OWASPRRBUSINESSIMPACTSCORE", "OWASPRRVECTOR" FROM "PUBLIC"."VULNERABILITY" [50000-214]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
        at org.h2.message.DbException.get(DbException.java:212)
        at org.h2.message.DbException.convert(DbException.java:395)
        at org.h2.command.Command.executeUpdate(Command.java:264)
        at org.h2.command.ddl.AlterTableAlterColumn.execute(AlterTableAlterColumn.java:645)
        at org.h2.command.ddl.AlterTableAlterColumn.cloneTableStructure(AlterTableAlterColumn.java:557)
        at org.h2.command.ddl.AlterTableAlterColumn.copyData(AlterTableAlterColumn.java:339)
        at org.h2.command.ddl.AlterTableAlterColumn.update(AlterTableAlterColumn.java:242)
        at org.h2.command.CommandContainer.update(CommandContainer.java:169)
        at org.h2.command.Command.executeUpdate(Command.java:252)
        at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:252)
        at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:223)
        at org.datanucleus.store.rdbms.datasource.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:194)
        at org.datanucleus.store.rdbms.datasource.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:194)
        at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatement(AbstractTable.java:799)
        at org.datanucleus.store.rdbms.table.AbstractTable.executeDdlStatementList(AbstractTable.java:749)
        at org.datanucleus.store.rdbms.table.TableImpl.validateColumns(TableImpl.java:235)
        at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.performTablesValidation(RDBMSStoreManager.java:3510)
        at org.datanucleus.store.rdbms.RDBMSStoreManager$ClassAdder.run(RDBMSStoreManager.java:3024)
        at org.datanucleus.store.rdbms.AbstractSchemaTransaction.execute(AbstractSchemaTransaction.java:118)
        at org.datanucleus.store.rdbms.RDBMSStoreManager.createSchemaForClasses(RDBMSStoreManager.java:3866)
        at org.datanucleus.store.schema.SchemaTool.createSchemaForClasses(SchemaTool.java:507)
        at org.datanucleus.PersistenceNucleusContextImpl.initialiseSchema(PersistenceNucleusContextImpl.java:824)
        at org.datanucleus.PersistenceNucleusContextImpl.initialise(PersistenceNucleusContextImpl.java:484)
        at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.freezeConfiguration(JDOPersistenceManagerFactory.java:865)
        at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.createPersistenceManagerFactory(JDOPersistenceManagerFactory.java:352)
        at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.getPersistenceManagerFactory(JDOPersistenceManagerFactory.java:275)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at javax.jdo.JDOHelper$16.run(JDOHelper.java:1975)
        at java.base/java.security.AccessController.doPrivileged(Unknown Source)
        at javax.jdo.JDOHelper.invoke(JDOHelper.java:1970)
        at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1139)
        at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:851)
        at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:1109)
        at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:969)
        at org.dependencytrack.upgrade.UpgradeInitializer.createPersistenceManagerFactory(UpgradeInitializer.java:121)
        at org.dependencytrack.upgrade.UpgradeInitializer.contextInitialized(UpgradeInitializer.java:68)
        at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:1050)
        at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:624)
        at org.eclipse.jetty.server.handler.ContextHandler.contextInitialized(ContextHandler.java:985)
        at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:740)
        at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:392)
        at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1304)
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:902)
        at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:306)
        at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:532)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
        at org.eclipse.jetty.server.Server.start(Server.java:470)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:89)
        at org.eclipse.jetty.server.Server.doStart(Server.java:415)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at alpine.embedded.EmbeddedJettyServer.main(EmbeddedJettyServer.java:100)
Caused by: java.lang.NullPointerException: Cannot read field "streamStoreId" because "<local11>" is null
        at org.h2.mvstore.db.LobStorageMap.copyLob(LobStorageMap.java:280)
        at org.h2.value.ValueLob.copyToResult(ValueLob.java:291)
        at org.h2.result.LocalResult.cloneLobs(LocalResult.java:357)
        at org.h2.result.LocalResult.addRow(LocalResult.java:409)
        at org.h2.command.query.Select.queryFlat(Select.java:730)
        at org.h2.command.query.Select.queryWithoutCache(Select.java:833)
        at org.h2.command.query.Query.queryWithoutCacheLazyCheck(Query.java:197)
        at org.h2.command.query.Query.query(Query.java:512)
        at org.h2.command.query.Query.query(Query.java:475)
        at org.h2.command.dml.Insert.insertRows(Insert.java:199)
        at org.h2.command.dml.Insert.update(Insert.java:135)
        at org.h2.command.dml.DataChangeStatement.update(DataChangeStatement.java:74)
        at org.h2.command.CommandContainer.update(CommandContainer.java:169)
        at org.h2.command.Command.executeUpdate(Command.java:252)
        ... 53 more

Yaytay avatar Jul 07 '23 08:07 Yaytay

Isn't that what we implemented already in one of last versions or do I misunderstand? There is a checkbox on the graph, allowing you to show outdated component status, which shows the icon in each graph node that has an outdated version.

rkg-mm avatar Aug 18 '23 19:08 rkg-mm

I do think that there is a wee bit of work outstanding here.

Testing with 4.11 SNAPSHOT, there is indeed a checkbox on the main dependency graph (accessesd via "Dependency Graph" tab) and the checkbox works in this view.

However, there is no checkbox when one views a filtered graph for a specific component. If one has already ticked the checkbox on the main graph then this preference is respected in the component graph and the out-of-date icon is displayed. But one cannot toggle "in-situ", which is a bit annoying.

I would prefer not to have the green triangle (anywhere - I don't think an OK symbol should ever be a triangle with an exclamation mark in it, and the colours chosen are not helpful for green/yellow colour blindness).

The accessibility issue was mentioned in #311 (which has now been closed with some changes made) but it does seem that things can still be improved. Accessibility is something that has to be taken seriously if DT is to be used by government organisations, etc.

msymons avatar May 01 '24 13:05 msymons