310 lines
10 KiB
Go
310 lines
10 KiB
Go
package util
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseAuthMethod_DefaultLocal(t *testing.T) {
|
|
t.Setenv("WGUI_AUTH_METHOD", "")
|
|
method := ParseAuthMethod()
|
|
if method != AuthMethodLocal {
|
|
t.Errorf("expected default auth method to be %q, got %q", AuthMethodLocal, method)
|
|
}
|
|
}
|
|
|
|
func TestParseAuthMethod_LocalExplicit(t *testing.T) {
|
|
t.Setenv("WGUI_AUTH_METHOD", "local")
|
|
method := ParseAuthMethod()
|
|
if method != AuthMethodLocal {
|
|
t.Errorf("expected auth method to be %q, got %q", AuthMethodLocal, method)
|
|
}
|
|
}
|
|
|
|
func TestParseAuthMethod_GitHubExplicit(t *testing.T) {
|
|
t.Setenv("WGUI_AUTH_METHOD", "github")
|
|
method := ParseAuthMethod()
|
|
if method != AuthMethodGitHub {
|
|
t.Errorf("expected auth method to be %q, got %q", AuthMethodGitHub, method)
|
|
}
|
|
}
|
|
|
|
func TestParseAuthMethod_GitHubCaseInsensitive(t *testing.T) {
|
|
t.Setenv("WGUI_AUTH_METHOD", "GitHub")
|
|
method := ParseAuthMethod()
|
|
if method != AuthMethodGitHub {
|
|
t.Errorf("expected case-insensitive auth method to be %q, got %q", AuthMethodGitHub, method)
|
|
}
|
|
}
|
|
|
|
func TestParseGitHubAuthConfig_NormalizesLists(t *testing.T) {
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "test-secret")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET_FILE", "")
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "http://localhost:8080/callback")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", " User1 ,user1, USER2 ")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", " OrgA ,orga ")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", " Admin1 , admin1 ")
|
|
|
|
config := ParseGitHubAuthConfig()
|
|
|
|
if config.ClientID != "test-client-id" {
|
|
t.Fatalf("expected client_id to be parsed, got %q", config.ClientID)
|
|
}
|
|
if config.ClientSecret != "test-secret" {
|
|
t.Fatalf("expected client_secret to be parsed, got %q", config.ClientSecret)
|
|
}
|
|
if config.RedirectURL != "http://localhost:8080/callback" {
|
|
t.Fatalf("expected redirect_url to be parsed, got %q", config.RedirectURL)
|
|
}
|
|
|
|
expectedUsers := []string{"user1", "user2"}
|
|
if len(config.AllowedUsers) != len(expectedUsers) {
|
|
t.Fatalf("expected %d allowed users, got %d", len(expectedUsers), len(config.AllowedUsers))
|
|
}
|
|
for i, user := range expectedUsers {
|
|
if config.AllowedUsers[i] != user {
|
|
t.Fatalf("expected allowed_users[%d]=%q, got %q", i, user, config.AllowedUsers[i])
|
|
}
|
|
}
|
|
|
|
expectedOrgs := []string{"orga"}
|
|
if len(config.AllowedOrgs) != len(expectedOrgs) {
|
|
t.Fatalf("expected %d allowed orgs, got %d", len(expectedOrgs), len(config.AllowedOrgs))
|
|
}
|
|
for i, org := range expectedOrgs {
|
|
if config.AllowedOrgs[i] != org {
|
|
t.Fatalf("expected allowed_orgs[%d]=%q, got %q", i, org, config.AllowedOrgs[i])
|
|
}
|
|
}
|
|
|
|
expectedAdmins := []string{"admin1"}
|
|
if len(config.AdminUsers) != len(expectedAdmins) {
|
|
t.Fatalf("expected %d admin users, got %d", len(expectedAdmins), len(config.AdminUsers))
|
|
}
|
|
for i, admin := range expectedAdmins {
|
|
if config.AdminUsers[i] != admin {
|
|
t.Fatalf("expected admin_users[%d]=%q, got %q", i, admin, config.AdminUsers[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_MissingClientID(t *testing.T) {
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET_FILE", "")
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "")
|
|
|
|
config := GitHubAuthConfig{}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err == nil {
|
|
t.Error("expected error for missing client_id, got nil")
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_MissingClientSecret(t *testing.T) {
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET_FILE", "")
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "")
|
|
|
|
config := GitHubAuthConfig{
|
|
ClientID: "test-client-id",
|
|
}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err == nil {
|
|
t.Error("expected error for missing client_secret and client_secret_file, got nil")
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_MissingClientSecretFile(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
secretFile := filepath.Join(tmpDir, "secret")
|
|
os.WriteFile(secretFile, []byte("test-secret"), 0600)
|
|
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET_FILE", secretFile)
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "")
|
|
|
|
config := GitHubAuthConfig{
|
|
ClientID: "test-client-id",
|
|
ClientSecretFile: secretFile,
|
|
}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err == nil {
|
|
t.Error("expected error for missing client_secret and client_secret_file with no readable content, got nil")
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_ClientSecretFileReadError(t *testing.T) {
|
|
nonExistentFile := "/nonexistent/path/to/secret"
|
|
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET_FILE", nonExistentFile)
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "")
|
|
|
|
config := GitHubAuthConfig{
|
|
ClientID: "test-client-id",
|
|
ClientSecretFile: nonExistentFile,
|
|
}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err == nil {
|
|
t.Error("expected error for unreadable client_secret_file, got nil")
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_MissingRedirectURL(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
secretFile := filepath.Join(tmpDir, "secret")
|
|
os.WriteFile(secretFile, []byte("test-secret"), 0600)
|
|
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "test-secret")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET_FILE", "")
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "")
|
|
|
|
config := GitHubAuthConfig{
|
|
ClientID: "test-client-id",
|
|
ClientSecret: "test-secret",
|
|
}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err == nil {
|
|
t.Error("expected error for missing redirect_url, got nil")
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_MissingAllowRules(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
secretFile := filepath.Join(tmpDir, "secret")
|
|
os.WriteFile(secretFile, []byte("test-secret"), 0600)
|
|
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "test-secret")
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "http://localhost:8080/callback")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "")
|
|
|
|
config := GitHubAuthConfig{
|
|
ClientID: "test-client-id",
|
|
ClientSecret: "test-secret",
|
|
RedirectURL: "http://localhost:8080/callback",
|
|
}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err == nil {
|
|
t.Error("expected error for missing allow rules (allowed_users or allowed_orgs), got nil")
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_MissingAdminUsers(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
secretFile := filepath.Join(tmpDir, "secret")
|
|
os.WriteFile(secretFile, []byte("test-secret"), 0600)
|
|
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "test-secret")
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "http://localhost:8080/callback")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "user1,user2")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "")
|
|
|
|
config := GitHubAuthConfig{
|
|
ClientID: "test-client-id",
|
|
ClientSecret: "test-secret",
|
|
RedirectURL: "http://localhost:8080/callback",
|
|
AllowedUsers: []string{"user1", "user2"},
|
|
AllowedOrgs: []string{},
|
|
}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err == nil {
|
|
t.Error("expected error for missing admin_users, got nil")
|
|
}
|
|
}
|
|
|
|
func TestValidateGitHubAuthConfig_ValidMinimal(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
secretFile := filepath.Join(tmpDir, "secret")
|
|
os.WriteFile(secretFile, []byte("test-secret"), 0600)
|
|
|
|
t.Setenv("WGUI_GITHUB_CLIENT_ID", "test-client-id")
|
|
t.Setenv("WGUI_GITHUB_CLIENT_SECRET", "test-secret")
|
|
t.Setenv("WGUI_GITHUB_REDIRECT_URL", "http://localhost:8080/callback")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_USERS", "user1,user2")
|
|
t.Setenv("WGUI_GITHUB_ALLOWED_ORGS", "")
|
|
t.Setenv("WGUI_GITHUB_ADMIN_USERS", "admin1")
|
|
|
|
config := GitHubAuthConfig{
|
|
ClientID: "test-client-id",
|
|
ClientSecret: "test-secret",
|
|
RedirectURL: "http://localhost:8080/callback",
|
|
AllowedUsers: []string{"user1", "user2"},
|
|
AdminUsers: []string{"admin1"},
|
|
}
|
|
err := ValidateGitHubAuthConfig(config)
|
|
if err != nil {
|
|
t.Errorf("expected no error for valid config, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestNormalizeUsernames_LowercaseAndTrim(t *testing.T) {
|
|
input := []string{" User1 ", "USER2", " user3 "}
|
|
expected := []string{"user1", "user2", "user3"}
|
|
result := NormalizeUsernames(input)
|
|
if len(result) != len(expected) {
|
|
t.Fatalf("expected length %d, got %d", len(expected), len(result))
|
|
}
|
|
for i, v := range result {
|
|
if v != expected[i] {
|
|
t.Errorf("expected[%d]=%q, got[%d]=%q", i, expected[i], i, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNormalizeUsernames_Deduplicate(t *testing.T) {
|
|
input := []string{"User1", "user1", "USER1", "User2"}
|
|
expected := []string{"user1", "user2"}
|
|
result := NormalizeUsernames(input)
|
|
if len(result) != len(expected) {
|
|
t.Fatalf("expected length %d, got %d", len(expected), len(result))
|
|
}
|
|
for i, v := range result {
|
|
if v != expected[i] {
|
|
t.Errorf("expected[%d]=%q, got[%d]=%q", i, expected[i], i, v)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNormalizeUsernames_Empty(t *testing.T) {
|
|
input := []string{}
|
|
expected := []string{}
|
|
result := NormalizeUsernames(input)
|
|
if len(result) != len(expected) {
|
|
t.Fatalf("expected length %d, got %d", len(expected), len(result))
|
|
}
|
|
}
|
|
|
|
func TestNormalizeUsernames_BlankEntriesDropped(t *testing.T) {
|
|
result := NormalizeUsernames([]string{"", " ", " user1 "})
|
|
if len(result) != 1 || result[0] != "user1" {
|
|
t.Fatalf("expected blank entries to be dropped, got %#v", result)
|
|
}
|
|
}
|