feat(build): add new filter directives.
This commit is contained in:
parent
2ca62215bc
commit
83691bbb1f
2 changed files with 207 additions and 0 deletions
75
pkg/prebuild/directive/filter.go
Normal file
75
pkg/prebuild/directive/filter.go
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
// apparmor.d - Full set of apparmor profiles
|
||||||
|
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
package directive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
oss "github.com/roddhjav/apparmor.d/pkg/os"
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FilterOnly struct {
|
||||||
|
DirectiveBase
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterExclude struct {
|
||||||
|
DirectiveBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Directives["only"] = &FilterOnly{
|
||||||
|
DirectiveBase: DirectiveBase{
|
||||||
|
message: "Only directive applied",
|
||||||
|
usage: `#aa:only <dist or familly>`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Directives["exclude"] = &FilterExclude{
|
||||||
|
DirectiveBase: DirectiveBase{
|
||||||
|
message: "Exclude directive applied",
|
||||||
|
usage: `#aa:exclude <dist or familly>`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterRuleForUs(opt *Option) bool {
|
||||||
|
return slices.Contains(maps.Keys(opt.Args), oss.Distribution) || slices.Contains(maps.Keys(opt.Args), oss.Family)
|
||||||
|
}
|
||||||
|
|
||||||
|
func filter(only bool, opt *Option, profile string) string {
|
||||||
|
if only && filterRuleForUs(opt) {
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
if !only && !filterRuleForUs(opt) {
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
|
||||||
|
inline := true
|
||||||
|
tmp := strings.Split(opt.Raw, Keyword)
|
||||||
|
if len(tmp) >= 1 {
|
||||||
|
left := strings.TrimSpace(tmp[0])
|
||||||
|
if len(left) == 0 {
|
||||||
|
inline = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if inline {
|
||||||
|
profile = strings.Replace(profile, opt.Raw, "", -1)
|
||||||
|
} else {
|
||||||
|
regRemoveParagraph := regexp.MustCompile(`(?s)` + opt.Raw + `\n.*?\n\n`)
|
||||||
|
profile = regRemoveParagraph.ReplaceAllString(profile, "")
|
||||||
|
}
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d FilterOnly) Apply(opt *Option, profile string) string {
|
||||||
|
return filter(true, opt, profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d FilterExclude) Apply(opt *Option, profile string) string {
|
||||||
|
return filter(false, opt, profile)
|
||||||
|
}
|
||||||
132
pkg/prebuild/directive/filter_test.go
Normal file
132
pkg/prebuild/directive/filter_test.go
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
// apparmor.d - Full set of apparmor profiles
|
||||||
|
// Copyright (C) 2021-2024 Alexandre Pujol <alexandre@pujol.io>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
package directive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
oss "github.com/roddhjav/apparmor.d/pkg/os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFilterOnly_Apply(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
dist string
|
||||||
|
family string
|
||||||
|
opt *Option
|
||||||
|
profile string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "inline",
|
||||||
|
dist: "debian",
|
||||||
|
family: "apt",
|
||||||
|
opt: &Option{
|
||||||
|
Name: "only",
|
||||||
|
Args: map[string]string{"apt": ""},
|
||||||
|
File: nil,
|
||||||
|
Raw: " @{bin}/arch-audit rPx, #aa:only apt",
|
||||||
|
},
|
||||||
|
profile: " @{bin}/arch-audit rPx, #aa:only apt",
|
||||||
|
want: " @{bin}/arch-audit rPx, #aa:only apt",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "paragraph",
|
||||||
|
dist: "arch",
|
||||||
|
family: "pacman",
|
||||||
|
opt: &Option{
|
||||||
|
Name: "only",
|
||||||
|
Args: map[string]string{"zypper": ""},
|
||||||
|
File: nil,
|
||||||
|
Raw: " #aa:only zypper",
|
||||||
|
},
|
||||||
|
profile: `
|
||||||
|
/tmp/apt-changelog-@{rand6}/ w,
|
||||||
|
/tmp/apt-changelog-@{rand6}/*.changelog rw,
|
||||||
|
owner /tmp/alpm_*/{,**} rw,
|
||||||
|
owner /tmp/apt-changelog-@{rand6}/.apt-acquire-privs-test.@{rand6} rw,
|
||||||
|
owner /tmp/packagekit* rw,
|
||||||
|
|
||||||
|
@{run}/systemd/inhibit/*.ref rw,
|
||||||
|
owner @{run}/systemd/users/@{uid} r,
|
||||||
|
|
||||||
|
#aa:only zypper
|
||||||
|
@{run}/zypp.pid rwk,
|
||||||
|
owner @{run}/zypp-rpm.pid rwk,
|
||||||
|
owner @{run}/zypp/packages/ r,
|
||||||
|
|
||||||
|
owner /dev/shm/AP_0x@{rand6}/{,**} rw,
|
||||||
|
owner /dev/shm/ r,`,
|
||||||
|
want: `
|
||||||
|
/tmp/apt-changelog-@{rand6}/ w,
|
||||||
|
/tmp/apt-changelog-@{rand6}/*.changelog rw,
|
||||||
|
owner /tmp/alpm_*/{,**} rw,
|
||||||
|
owner /tmp/apt-changelog-@{rand6}/.apt-acquire-privs-test.@{rand6} rw,
|
||||||
|
owner /tmp/packagekit* rw,
|
||||||
|
|
||||||
|
@{run}/systemd/inhibit/*.ref rw,
|
||||||
|
owner @{run}/systemd/users/@{uid} r,
|
||||||
|
|
||||||
|
owner /dev/shm/AP_0x@{rand6}/{,**} rw,
|
||||||
|
owner /dev/shm/ r,`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
oss.Distribution = tt.dist
|
||||||
|
oss.Family = tt.family
|
||||||
|
if got := Directives["only"].Apply(tt.opt, tt.profile); got != tt.want {
|
||||||
|
t.Errorf("FilterOnly.Apply() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilterExclude_Apply(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
dist string
|
||||||
|
family string
|
||||||
|
opt *Option
|
||||||
|
profile string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "inline",
|
||||||
|
dist: "debian",
|
||||||
|
family: "apt",
|
||||||
|
opt: &Option{
|
||||||
|
Name: "exclude",
|
||||||
|
Args: map[string]string{"debian": ""},
|
||||||
|
File: nil,
|
||||||
|
Raw: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||||
|
},
|
||||||
|
profile: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||||
|
want: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "inline-keep",
|
||||||
|
dist: "whonix",
|
||||||
|
family: "apt",
|
||||||
|
opt: &Option{
|
||||||
|
Name: "exclude",
|
||||||
|
Args: map[string]string{"debian": ""},
|
||||||
|
File: nil,
|
||||||
|
Raw: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||||
|
},
|
||||||
|
profile: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||||
|
want: " @{bin}/dpkg rPx -> child-dpkg, #aa:exclude debian",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
oss.Distribution = tt.dist
|
||||||
|
oss.Family = tt.family
|
||||||
|
if got := Directives["exclude"].Apply(tt.opt, tt.profile); got != tt.want {
|
||||||
|
t.Errorf("FilterExclude.Apply() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue