setting_security_test.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package service
  2. import (
  3. "path/filepath"
  4. "testing"
  5. "github.com/mhsanaei/3x-ui/v3/database"
  6. )
  7. func setupSettingTestDB(t *testing.T) {
  8. t.Helper()
  9. if err := database.InitDB(filepath.Join(t.TempDir(), "x-ui.db")); err != nil {
  10. t.Fatal(err)
  11. }
  12. t.Cleanup(func() {
  13. if err := database.CloseDB(); err != nil {
  14. t.Fatal(err)
  15. }
  16. })
  17. }
  18. func TestGetAllSettingViewRedactsSecrets(t *testing.T) {
  19. setupSettingTestDB(t)
  20. s := &SettingService{}
  21. if err := s.saveSetting("tgBotToken", "telegram-secret"); err != nil {
  22. t.Fatal(err)
  23. }
  24. if err := s.saveSetting("twoFactorToken", "totp-secret"); err != nil {
  25. t.Fatal(err)
  26. }
  27. if err := s.saveSetting("ldapPassword", "ldap-secret"); err != nil {
  28. t.Fatal(err)
  29. }
  30. if err := s.saveSetting("apiToken", "api-secret"); err != nil {
  31. t.Fatal(err)
  32. }
  33. view, err := s.GetAllSettingView()
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. if view.TgBotToken != "" || view.TwoFactorToken != "" || view.LdapPassword != "" {
  38. t.Fatalf("settings view leaked secrets: %#v", view)
  39. }
  40. if !view.HasTgBotToken || !view.HasTwoFactorToken || !view.HasLdapPassword || !view.HasApiToken {
  41. t.Fatalf("settings view did not report configured secret flags: %#v", view)
  42. }
  43. }
  44. func TestUpdateAllSettingPreservesRedactedSecrets(t *testing.T) {
  45. setupSettingTestDB(t)
  46. s := &SettingService{}
  47. if err := s.saveSetting("tgBotToken", "telegram-secret"); err != nil {
  48. t.Fatal(err)
  49. }
  50. if err := s.saveSetting("ldapPassword", "ldap-secret"); err != nil {
  51. t.Fatal(err)
  52. }
  53. if err := s.saveSetting("twoFactorEnable", "true"); err != nil {
  54. t.Fatal(err)
  55. }
  56. if err := s.saveSetting("twoFactorToken", "totp-secret"); err != nil {
  57. t.Fatal(err)
  58. }
  59. view, err := s.GetAllSettingView()
  60. if err != nil {
  61. t.Fatal(err)
  62. }
  63. settings := &view.AllSetting
  64. if err := s.UpdateAllSetting(settings); err != nil {
  65. t.Fatal(err)
  66. }
  67. if got, _ := s.GetTgBotToken(); got != "telegram-secret" {
  68. t.Fatalf("tg token = %q, want preserved secret", got)
  69. }
  70. if got, _ := s.GetLdapPassword(); got != "ldap-secret" {
  71. t.Fatalf("ldap password = %q, want preserved secret", got)
  72. }
  73. if got, _ := s.GetTwoFactorToken(); got != "totp-secret" {
  74. t.Fatalf("2fa token = %q, want preserved secret", got)
  75. }
  76. }
  77. func TestSanitizePublicHTTPURLBlocksPrivateAddressUnlessAllowed(t *testing.T) {
  78. if _, err := SanitizePublicHTTPURL("http://127.0.0.1:8080/hook", false); err == nil {
  79. t.Fatal("expected localhost URL to be blocked")
  80. }
  81. if got, err := SanitizePublicHTTPURL("http://127.0.0.1:8080/hook", true); err != nil || got != "http://127.0.0.1:8080/hook" {
  82. t.Fatalf("allowPrivate result = %q, %v", got, err)
  83. }
  84. }