mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-30 20:40:09 +00:00
fix: Update runtime config when toggling Docker update actions setting
The DisableDockerUpdateActions setting was being saved to disk but not updated in h.config, causing the UI toggle to appear to revert on page refresh since the API returned the stale runtime value. Related to #1023
This commit is contained in:
parent
fbbefa4546
commit
9e339957c6
52 changed files with 4820 additions and 362 deletions
|
|
@ -1,6 +1,10 @@
|
|||
package main
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAuthorizePeer(t *testing.T) {
|
||||
p := &Proxy{
|
||||
|
|
@ -234,3 +238,160 @@ func TestDedupeStrings(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitAuthRules(t *testing.T) {
|
||||
p := &Proxy{
|
||||
config: &Config{
|
||||
AllowedPeers: []PeerConfig{
|
||||
{UID: 1001, Capabilities: []string{"read", "write"}},
|
||||
},
|
||||
AllowedPeerUIDs: []uint32{1002, 1002},
|
||||
AllowedPeerGIDs: []uint32{2001},
|
||||
},
|
||||
}
|
||||
|
||||
if err := p.initAuthRules(); err != nil {
|
||||
t.Fatalf("initAuthRules failed: %v", err)
|
||||
}
|
||||
|
||||
if _, ok := p.allowedPeerUIDs[1001]; !ok {
|
||||
t.Error("expected UID 1001 to be allowed")
|
||||
}
|
||||
if caps := p.peerCapabilities[1001]; !caps.Has(CapabilityWrite) {
|
||||
t.Error("expected UID 1001 to have write capability")
|
||||
}
|
||||
|
||||
if _, ok := p.allowedPeerUIDs[1002]; !ok {
|
||||
t.Error("expected UID 1002 to be allowed")
|
||||
}
|
||||
if caps := p.peerCapabilities[1002]; !caps.Has(CapabilityAdmin) {
|
||||
t.Error("expected UID 1002 to have legacy all capabilities")
|
||||
}
|
||||
|
||||
if _, ok := p.allowedPeerGIDs[2001]; !ok {
|
||||
t.Error("expected GID 2001 to be allowed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadSubIDRanges(t *testing.T) {
|
||||
tmpFile, err := os.CreateTemp("", "subuid")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(tmpFile.Name())
|
||||
|
||||
content := `root:100000:65536
|
||||
# commented:line:100
|
||||
user1:200000:1000
|
||||
invalid:start:65536
|
||||
toolong:100:notanumber
|
||||
short:line
|
||||
zero:300000:0
|
||||
`
|
||||
if err := os.WriteFile(tmpFile.Name(), []byte(content), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Test with filter
|
||||
ranges, err := loadSubIDRanges(tmpFile.Name(), []string{"root", "user1"})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if len(ranges) != 2 {
|
||||
t.Fatalf("expected 2 ranges, got %d", len(ranges))
|
||||
}
|
||||
|
||||
// Test without filter (should return all valid)
|
||||
ranges, err = loadSubIDRanges(tmpFile.Name(), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
// root and user1 are valid. zero has length 0 so skipped. invalid/toolong/short are invalid.
|
||||
if len(ranges) != 2 {
|
||||
t.Fatalf("expected 2 ranges, got %d", len(ranges))
|
||||
}
|
||||
|
||||
// Test missing file
|
||||
ranges, err = loadSubIDRanges("/nonexistent/file", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("expected no error for nonexistent file, got %v", err)
|
||||
}
|
||||
if ranges != nil {
|
||||
t.Fatal("expected nil ranges for nonexistent file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorizePeerEdgeCases(t *testing.T) {
|
||||
p := &Proxy{
|
||||
config: &Config{},
|
||||
}
|
||||
|
||||
if _, err := p.authorizePeer(nil); err == nil {
|
||||
t.Error("expected error for nil credentials")
|
||||
}
|
||||
|
||||
p.config.AllowIDMappedRoot = true
|
||||
// No ranges loaded
|
||||
if p.isIDMappedRoot(&peerCredentials{uid: 100000, gid: 100000}) {
|
||||
t.Error("expected isIDMappedRoot to be false when no ranges loaded")
|
||||
}
|
||||
|
||||
p.idMappedUIDRanges = []idRange{{start: 100000, length: 1000}}
|
||||
p.idMappedGIDRanges = []idRange{{start: 100000, length: 1000}}
|
||||
|
||||
if !p.isIDMappedRoot(&peerCredentials{uid: 100500, gid: 100500}) {
|
||||
t.Error("expected isIDMappedRoot to be true for valid range")
|
||||
}
|
||||
|
||||
if p.isIDMappedRoot(&peerCredentials{uid: 200000, gid: 100500}) {
|
||||
t.Error("expected isIDMappedRoot to be false for invalid UID")
|
||||
}
|
||||
|
||||
if p.isIDMappedRoot(&peerCredentials{uid: 100500, gid: 200000}) {
|
||||
t.Error("expected isIDMappedRoot to be false for invalid GID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadIDMappingRanges(t *testing.T) {
|
||||
// We can't easily mock /etc/subuid but we can call it to get coverage
|
||||
_, _, _ = loadIDMappingRanges([]string{"root"})
|
||||
}
|
||||
|
||||
func TestLoadIDMappingRanges_Error(t *testing.T) {
|
||||
// Save old paths
|
||||
oldUID := subUIDPath
|
||||
oldGID := subGIDPath
|
||||
defer func() {
|
||||
subUIDPath = oldUID
|
||||
subGIDPath = oldGID
|
||||
}()
|
||||
|
||||
// Point to directory to cause read error
|
||||
tmpDir := t.TempDir()
|
||||
subUIDPath = tmpDir
|
||||
subGIDPath = tmpDir
|
||||
|
||||
_, _, err := loadIDMappingRanges([]string{"root"})
|
||||
if err == nil {
|
||||
t.Error("expected error when UID file is a directory")
|
||||
}
|
||||
|
||||
// Make UID valid (empty file is valid) but GID invalid
|
||||
uidFile := filepath.Join(tmpDir, "uid")
|
||||
os.WriteFile(uidFile, []byte("root:100000:65536"), 0644)
|
||||
subUIDPath = uidFile
|
||||
|
||||
_, _, err = loadIDMappingRanges([]string{"root"})
|
||||
if err == nil {
|
||||
t.Error("expected error when GID file is a directory")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadSubIDRanges_ReadError(t *testing.T) {
|
||||
// Passing a directory as a file path should trigger a read error
|
||||
dir := t.TempDir()
|
||||
_, err := loadSubIDRanges(dir, []string{"root"})
|
||||
if err == nil {
|
||||
t.Error("expected error when reading a directory")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue