199 lines
5.4 KiB
Go
199 lines
5.4 KiB
Go
package auth
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/perfect-panel/server/internal/config"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestNormalizeEmail(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
want string
|
|
}{
|
|
// Gmail dot trick
|
|
{"a.v.x.xx@gmail.com", "avxxx@gmail.com"},
|
|
{"john.doe@gmail.com", "johndoe@gmail.com"},
|
|
{"a.b.c.d.e@gmail.com", "abcde@gmail.com"},
|
|
// Gmail + alias
|
|
{"user+tag@gmail.com", "user@gmail.com"},
|
|
{"a.b+tag@gmail.com", "ab@gmail.com"},
|
|
// Googlemail
|
|
{"a.b@googlemail.com", "ab@googlemail.com"},
|
|
// Non-Gmail: dots preserved
|
|
{"john.doe@outlook.com", "john.doe@outlook.com"},
|
|
{"john.doe@qq.com", "john.doe@qq.com"},
|
|
// + alias stripped for all providers
|
|
{"user+spam@outlook.com", "user@outlook.com"},
|
|
{"user+spam@qq.com", "user@qq.com"},
|
|
// Case insensitive
|
|
{"User@Gmail.COM", "user@gmail.com"},
|
|
{"A.B@Gmail.com", "ab@gmail.com"},
|
|
// No change for normal non-gmail email
|
|
{"abc@163.com", "abc@163.com"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.input, func(t *testing.T) {
|
|
got := NormalizeEmail(tt.input)
|
|
if got != tt.want {
|
|
t.Errorf("NormalizeEmail(%q) = %q, want %q", tt.input, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNormalizeEmail_NoChangeSkipsCheck(t *testing.T) {
|
|
// These emails should NOT trigger cross-user check (normalized == original)
|
|
noChangeCases := []string{
|
|
"abc@163.com",
|
|
"john.doe@outlook.com",
|
|
"user@qq.com",
|
|
}
|
|
for _, email := range noChangeCases {
|
|
normalized := NormalizeEmail(email)
|
|
lower := email
|
|
if normalized == lower {
|
|
// correct: no normalization change, NormalizedEmailHasTrial would return false early
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestShouldGrantTrialForEmail(t *testing.T) {
|
|
// 模拟线上配置:白名单开启,gmail.com 也在名单里
|
|
rcWithGmail := config.RegisterConfig{
|
|
EnableTrial: true,
|
|
EnableTrialEmailWhitelist: true,
|
|
TrialEmailDomainWhitelist: "hifastapp.com,hifastvpn.com,126.com,139.com,163.com,gmail.com",
|
|
}
|
|
// 白名单关闭
|
|
rcNoWhitelist := config.RegisterConfig{
|
|
EnableTrial: true,
|
|
EnableTrialEmailWhitelist: false,
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
rc config.RegisterConfig
|
|
email string
|
|
want bool
|
|
reason string
|
|
}{
|
|
{
|
|
name: "gmail dot trick - blocked even if gmail.com in whitelist",
|
|
rc: rcWithGmail,
|
|
email: "s.m.s.n.fsmbt.d.ndny@gmail.com",
|
|
want: false,
|
|
reason: "gmail 泛域名(含点号)应拒绝",
|
|
},
|
|
{
|
|
name: "gmail plus alias - blocked",
|
|
rc: rcWithGmail,
|
|
email: "user+tag@gmail.com",
|
|
want: false,
|
|
reason: "gmail +别名应拒绝",
|
|
},
|
|
{
|
|
name: "clean gmail - allowed",
|
|
rc: rcWithGmail,
|
|
email: "normaluser@gmail.com",
|
|
want: true,
|
|
reason: "干净的 gmail 应放行",
|
|
},
|
|
{
|
|
name: "163 with dot - allowed (non-gmail dot is ok)",
|
|
rc: rcWithGmail,
|
|
email: "s.m.s.n@163.com",
|
|
want: true,
|
|
reason: "非 gmail 域点号不拦截",
|
|
},
|
|
{
|
|
name: "163 plus alias - blocked",
|
|
rc: rcWithGmail,
|
|
email: "user+spam@163.com",
|
|
want: false,
|
|
reason: "所有域名的 +别名都拦截",
|
|
},
|
|
{
|
|
name: "gmail typo squatting domain - blocked even if accidentally whitelisted",
|
|
rc: config.RegisterConfig{EnableTrial: true, EnableTrialEmailWhitelist: true, TrialEmailDomainWhitelist: "gmail.com,gmaial.com"},
|
|
email: "1.2.3.4xxx@gmaial.com",
|
|
want: false,
|
|
reason: "易混淆 Gmail 域名不应发放试用",
|
|
},
|
|
{
|
|
name: "invalid empty local - blocked",
|
|
rc: rcWithGmail,
|
|
email: "@gmail.com",
|
|
want: false,
|
|
reason: "邮箱 local 为空应拒绝",
|
|
},
|
|
{
|
|
name: "subdomain spoof - blocked",
|
|
rc: rcWithGmail,
|
|
email: "user@fake.gmail.com",
|
|
want: false,
|
|
reason: "白名单必须精确匹配域名,不匹配子域",
|
|
},
|
|
{
|
|
name: "whitelist disabled - gmail dot trick still blocked",
|
|
rc: rcNoWhitelist,
|
|
email: "s.m.s.n.fsmbt.d.ndny@gmail.com",
|
|
want: false,
|
|
reason: "白名单未启用,但泛域名仍应拒绝",
|
|
},
|
|
{
|
|
name: "trial disabled - always blocked",
|
|
rc: config.RegisterConfig{EnableTrial: false},
|
|
email: "user@163.com",
|
|
want: false,
|
|
reason: "试用未开启",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := ShouldGrantTrialForEmail(tt.rc, tt.email)
|
|
if got != tt.want {
|
|
t.Errorf("ShouldGrantTrialForEmail(%q) = %v, want %v | reason: %s",
|
|
tt.email, got, tt.want, tt.reason)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestShouldAutoGrantTrialOnPublicEmailFlows(t *testing.T) {
|
|
assert.False(t, ShouldAutoGrantTrialOnPublicEmailFlows(config.RegisterConfig{}))
|
|
assert.False(t, ShouldAutoGrantTrialOnPublicEmailFlows(config.RegisterConfig{
|
|
EnableTrial: true,
|
|
EnableTrialEmailWhitelist: true,
|
|
TrialEmailDomainWhitelist: "gmail.com,example.com",
|
|
}))
|
|
}
|
|
|
|
func TestIsEmailDomainWhitelisted(t *testing.T) {
|
|
whitelist := "gmail.com,edu.cn,outlook.com"
|
|
tests := []struct {
|
|
email string
|
|
want bool
|
|
}{
|
|
{"user@gmail.com", true},
|
|
{"user@edu.cn", true},
|
|
{"User@Gmail.COM", true},
|
|
{"user@yahoo.com", false},
|
|
{"user@fake.gmail.com", false}, // subdomain not matched
|
|
{"user@", false},
|
|
{"notanemail", false},
|
|
{"@gmail.com", false},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.email, func(t *testing.T) {
|
|
got := IsEmailDomainWhitelisted(tt.email, whitelist)
|
|
if got != tt.want {
|
|
t.Errorf("IsEmailDomainWhitelisted(%q) = %v, want %v", tt.email, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|