ui/lib/modules/my_services/widgets/vulnerabilities.dart (152 lines of code) (raw):
// Copyright 2023 Google LLC
//
// 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.
import 'package:cloudprovision/modules/my_services/models/service.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../utils/styles.dart';
import '../data/security_repository.dart';
class VulnerabilityWidget extends ConsumerStatefulWidget {
final Service service;
const VulnerabilityWidget({
super.key,
required this.service,
});
@override
ConsumerState<VulnerabilityWidget> createState() => _VulnerabilityWidgetState();
}
class _VulnerabilityWidgetState extends ConsumerState<VulnerabilityWidget> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return buildVulnerabilitiesSection();
}
buildVulnerabilitiesSection() {
var containerVulnerabilities = ref.watch(containerVulnerabilitiesProvider(
projectId: widget.service.projectId,
serviceId: widget.service.serviceId));
return containerVulnerabilities.when(
loading: () => LinearProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (vulnerabilities) {
var vulnerabilitiesMap = {};
vulnerabilities.forEach((vuln) {
if (vulnerabilitiesMap.containsKey(vuln.resourceUri)) {
List<Map<String, String>> vulnList =
vulnerabilitiesMap[vuln.resourceUri];
Map<String, String> tmpVulnMap = {};
tmpVulnMap['fixableCount'] = vuln.fixableCount;
tmpVulnMap['totalCount'] = vuln.totalCount;
tmpVulnMap['severity'] = vuln.severity;
vulnList.add(tmpVulnMap);
} else {
List<Map<String, String>> tmpVulnList = [];
vulnerabilitiesMap[vuln.resourceUri] = tmpVulnList;
Map<String, String> tmpVulnMap = {};
tmpVulnMap['fixableCount'] = vuln.fixableCount;
tmpVulnMap['totalCount'] = vuln.totalCount;
tmpVulnMap['severity'] = vuln.severity;
tmpVulnList.add(tmpVulnMap);
}
});
List<Widget> rows = [];
vulnerabilitiesMap.entries.forEach((element) {
String name = element.key as String;
name = name.substring(
name.indexOf("sha256:") + 7, name.indexOf("sha256:") + 7 + 12);
rows.add(Row(
children: [
Text(
"Container: ",
style: AppText.fontStyle,
),
SizedBox(
width: 4,
),
TextButton(
onPressed: () async {
final Uri _url = Uri.parse(element.key as String);
if (!await launchUrl(_url)) {
throw 'Could not launch $_url';
}
},
child: Text(
"${widget.service.serviceId}@${name}",
overflow: TextOverflow.ellipsis,
maxLines: 1,
style: AppText.linkFontStyle,
),
),
],
));
rows.add(Row(
children: [
SizedBox(
width: 120,
child: Text(
"Severity",
style: AppText.fontStyleBold,
),
),
SizedBox(
width: 4,
),
SizedBox(
width: 100,
child: Text(
"Total",
style: AppText.fontStyleBold,
),
),
SizedBox(
width: 4,
),
SizedBox(
child: Text(
"Fixable",
style: AppText.fontStyleBold,
),
),
],
));
List<Map<String, String>> mv = element.value;
mv.forEach((el) {
rows.add(Row(
children: [
SizedBox(
width: 130,
child: Text(
"${el['severity']}",
style: AppText.fontStyle,
),
),
SizedBox(
width: 4,
),
SizedBox(
width: 110,
child: Text(
"${el['totalCount']}",
style: AppText.fontStyle,
),
),
SizedBox(
width: 4,
),
SizedBox(
child: Text(
"${el['fixableCount']}",
style: AppText.fontStyle,
),
),
],
));
});
});
return Column(
children: rows,
);
});
}
}