mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-07 08:57:12 +00:00
141 lines
4 KiB
Go
141 lines
4 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/config"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestHandleSSHConfig_AllowedDirectives(t *testing.T) {
|
|
// Setup temporary home directory
|
|
tempHome := t.TempDir()
|
|
t.Setenv("HOME", tempHome)
|
|
|
|
handler := &SystemSettingsHandler{} // No dependencies needed for this handler
|
|
|
|
validConfig := `
|
|
Host bastion
|
|
Hostname 1.2.3.4
|
|
User pulse
|
|
IdentityFile ~/.ssh/id_rsa
|
|
StrictHostKeyChecking no
|
|
|
|
Host internal
|
|
ProxyJump bastion
|
|
User internal
|
|
`
|
|
req := httptest.NewRequest(http.MethodPost, "/api/config/ssh", strings.NewReader(validConfig))
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.HandleSSHConfig(w, req)
|
|
|
|
require.Equal(t, http.StatusOK, w.Code)
|
|
|
|
// Verify file was written
|
|
configPath := filepath.Join(tempHome, ".ssh", "config")
|
|
content, err := os.ReadFile(configPath)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, validConfig, string(content))
|
|
}
|
|
|
|
func TestHandleSSHConfig_ForbiddenDirectives(t *testing.T) {
|
|
handler := &SystemSettingsHandler{}
|
|
|
|
forbiddenConfig := `
|
|
Host bad
|
|
PermitRootLogin yes
|
|
`
|
|
req := httptest.NewRequest(http.MethodPost, "/api/config/ssh", strings.NewReader(forbiddenConfig))
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.HandleSSHConfig(w, req)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
assert.Contains(t, w.Body.String(), "forbidden directive")
|
|
}
|
|
|
|
func TestHandleSSHConfig_Empty(t *testing.T) {
|
|
handler := &SystemSettingsHandler{}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/config/ssh", strings.NewReader(""))
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.HandleSSHConfig(w, req)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
assert.Contains(t, w.Body.String(), "Empty SSH config")
|
|
}
|
|
|
|
func TestHandleSSHConfig_TooLarge(t *testing.T) {
|
|
handler := &SystemSettingsHandler{}
|
|
|
|
// 32KB + 1 byte
|
|
largeConfig := string(make([]byte, 32*1024+1))
|
|
req := httptest.NewRequest(http.MethodPost, "/api/config/ssh", strings.NewReader(largeConfig))
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.HandleSSHConfig(w, req)
|
|
|
|
// Expect 413 Payload Too Large OR 400 Bad Request depending on how MaxBytesReader behaves
|
|
// The implementation checks for MaxBytesError and returns 413
|
|
assert.Equal(t, http.StatusRequestEntityTooLarge, w.Code)
|
|
}
|
|
|
|
func TestHandleSSHConfig_WrongMethod(t *testing.T) {
|
|
handler := &SystemSettingsHandler{}
|
|
req := httptest.NewRequest(http.MethodGet, "/api/config/ssh", nil)
|
|
w := httptest.NewRecorder()
|
|
handler.HandleSSHConfig(w, req)
|
|
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
|
|
}
|
|
|
|
func TestHandleSSHConfig_HardensExistingPermissions(t *testing.T) {
|
|
tempHome := t.TempDir()
|
|
t.Setenv("HOME", tempHome)
|
|
|
|
sshDir := filepath.Join(tempHome, ".ssh")
|
|
require.NoError(t, os.MkdirAll(sshDir, 0o755))
|
|
configPath := filepath.Join(sshDir, "config")
|
|
require.NoError(t, os.WriteFile(configPath, []byte("Host old\n\tHostname old.example\n"), 0o644))
|
|
require.NoError(t, os.Chmod(sshDir, 0o755))
|
|
require.NoError(t, os.Chmod(configPath, 0o644))
|
|
|
|
handler := &SystemSettingsHandler{}
|
|
validConfig := "Host bastion\n\tHostname 1.2.3.4\n\tUser pulse\n"
|
|
req := httptest.NewRequest(http.MethodPost, "/api/config/ssh", strings.NewReader(validConfig))
|
|
w := httptest.NewRecorder()
|
|
|
|
handler.HandleSSHConfig(w, req)
|
|
require.Equal(t, http.StatusOK, w.Code)
|
|
|
|
sshDirInfo, err := os.Stat(sshDir)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, os.FileMode(0o700), sshDirInfo.Mode().Perm())
|
|
|
|
configInfo, err := os.Stat(configPath)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, os.FileMode(0o600), configInfo.Mode().Perm())
|
|
}
|
|
|
|
func TestSetMonitor(t *testing.T) {
|
|
handler := &SystemSettingsHandler{}
|
|
monitor := &mockMonitor{} // mockMonitor is defined in system_settings_handlers_test.go (same package)
|
|
|
|
handler.SetMonitor(monitor)
|
|
assert.Equal(t, monitor, handler.defaultMonitor)
|
|
}
|
|
|
|
func TestSetConfig(t *testing.T) {
|
|
handler := &SystemSettingsHandler{}
|
|
cfg := &config.Config{AuthUser: "test"}
|
|
|
|
handler.SetConfig(cfg)
|
|
assert.Equal(t, cfg, handler.config)
|
|
}
|