{% extends "base.html" %} {# Supply chain audit indicators. Flags render green (pass), red (fail) or neutral grey (not audited yet). Registration has a fourth state, 2, which renders yellow: the chain does carry a registration, but its *source* reference - the git commit, not the rpm-md binary checksum the build is keyed on - is too weak to verify against. The binary checksum cannot be the weak one: it is the lookup key, so a build either has a full digest or was never polled at all. Colour is never the only signal - every indicator carries a title with the spelled out state, and the security badge also names the worst severity and the issue count. The *_icon macros are the compact form for the build table, the *_detail macros the spelled out form used by supply_chain_audit_box(), the box shown inside Product Information. Icon names must exist in FontAwesome 6.0.0 (the version base.html loads) - later v6 names such as fa-shield-halved are not in it and render as nothing. #} {# Severity vocabulary of the security_issues column, worst first. Two of them, because the column has two producers. The chain monitor writes what the contract's SecurityLevel flag says (low, moderate, important, critical), and the import API lets a caller push the older low/medium/high/ critical wording. Both are listed so neither is dropped on the floor: a severity this list does not name used to render as green "none known", which states the opposite of the truth. Anything still unrecognized is shown too, in a neutral badge, and ranked ahead of everything we can rank: an unplaceable severity might be the worst one there is, and the badge is a warning rather than a score, so the safe reading is the loud one. See SEVERITY_ORDER in the JS below, which has to stay in step with this list. #} {% set severity_levels = ['critical', 'important', 'high', 'moderate', 'medium', 'low'] %} {% macro audit_flag(state, icon, label, ok_text, fail_text, pending_text='not audited yet', warning_text='weak source reference') -%} {%- if state is none -%} {%- elif state == 2 -%} {%- elif state -%} {%- else -%} {%- endif -%} {%- endmacro %} {# The severity is the whole answer, so nothing here counts anything. A build has exactly one security level: the contract derives it from the nearest report at or after that build, get_product_build() returns the one number, and security_issues_for() mirrors it as {level: 1}. The column is a dict only because it predates the chain being its only writer; the values are carried but never shown, because "1 low (1 total)" was arithmetic about a number that cannot vary. A level is present when its value is truthy, which is what keeps a stored zero from reading as a report. #} {% macro security_issues_icon(issues) -%} {%- if issues is none -%} {%- else -%} {#- Unrankable severities first, then the known ones worst first, so the first hit is always the one to put on the badge -#} {%- set ordered = (issues | reject('in', severity_levels) | sort | list) + severity_levels -%} {%- set ns = namespace(present=[]) -%} {%- for level in ordered -%} {%- if issues.get(level) -%} {%- set ns.present = ns.present + [level] -%} {%- endif -%} {%- endfor -%} {%- if not ns.present -%} {%- else -%} {#- The badge names the worst severity; the title names all of them -#} {{ ns.present[0] }} {%- endif -%} {%- endif -%} {%- endmacro %} {% macro audit_flag_detail(state, icon, ok_text, fail_text, pending_text='Not audited yet', warning_text='Weak source reference') -%} {%- if state is none -%} {{ pending_text }} {%- elif state == 2 -%} {{ warning_text }} {%- elif state -%} {{ ok_text }} {%- else -%} {{ fail_text }} {%- endif -%} {%- endmacro %} {% macro security_issues_detail(issues) -%} {%- if issues is none -%} None known yet {%- else -%} {%- set ns = namespace(any=false) -%} {%- for level in (issues | reject('in', severity_levels) | sort | list) + severity_levels -%} {%- if issues.get(level) -%} {%- set ns.any = true -%} {{ level }} {%- endif -%} {%- endfor -%} {%- if not ns.any -%} None known {%- endif -%} {%- endif -%} {%- endmacro %} {# The audit indicators get their own box inside Product Information, with a help button opening the shared #supplyChainInfoModal defined at the end of the page (one modal for the whole page - Bootstrap's data-api toggling is delegated, so it also works for the JS injected Debug/Source rows). #} {# Shown in place of nothing when the monitor has stopped because it cannot read the contract. The flags below are not cleared - they were true when they were written - so this is the only thing on the page that says how old they are. #} {% macro contract_incompatible_notice(status, compact=false) -%}
{{ chain_network.contract }}
{%- else -%}
{{ chain_network.contract }}
{%- endif %}
SPDX Product Data
The cache daemon is currently rebuilding the database. Product data will appear here once the SPDX scan completes. This process may take several minutes depending on the number of SPDX files.
Projects and basic OBS data are being indexed first. SPDX product data will follow. Check the daemon logs for progress.
{{ grouped_products | length }} product-version(s), {{ total_product_count }} total build(s)
Initializing search interface...
The cache daemon is currently rebuilding the database.
Product data will appear here automatically once the SPDX scan completes.
Please wait a few minutes and refresh this page.
No SPDX product data available in cache.
Configure SPDX scanning in config.ini under [spdx] section.
Then restart the cache daemon to populate SPDX data.