feat: backend core - auth, user, role, permission, device, webhook, monitoring, cache, repository, service, middleware, API handlers

This commit is contained in:
2026-04-02 11:19:50 +08:00
parent e59a77bc49
commit dcc1f186f8
298 changed files with 62603 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
package providers
import (
"net/url"
"strings"
"testing"
)
func TestGitHubProviderGetAuthURLEscapesRedirectAndState(t *testing.T) {
provider := NewGitHubProvider("client-id", "client-secret", "https://admin.example.com/login/oauth/callback")
authURL, err := provider.GetAuthURL("state value")
if err != nil {
t.Fatalf("GetAuthURL failed: %v", err)
}
parsed, err := url.Parse(authURL)
if err != nil {
t.Fatalf("parse auth url failed: %v", err)
}
query := parsed.Query()
if query.Get("client_id") != "client-id" {
t.Fatalf("expected client_id to be propagated, got %q", query.Get("client_id"))
}
if query.Get("redirect_uri") != "https://admin.example.com/login/oauth/callback" {
t.Fatalf("expected redirect_uri to be propagated, got %q", query.Get("redirect_uri"))
}
if query.Get("state") != "state value" {
t.Fatalf("expected state to be propagated, got %q", query.Get("state"))
}
if !strings.Contains(query.Get("scope"), "read:user") {
t.Fatalf("expected GitHub scope to include read:user, got %q", query.Get("scope"))
}
}
func TestGoogleProviderGenerateStateAndBuildAuthURL(t *testing.T) {
provider := NewGoogleProvider("google-client", "google-secret", "https://admin.example.com/login/oauth/callback")
stateA, err := provider.GenerateState()
if err != nil {
t.Fatalf("GenerateState failed: %v", err)
}
stateB, err := provider.GenerateState()
if err != nil {
t.Fatalf("GenerateState failed: %v", err)
}
if stateA == "" || stateB == "" {
t.Fatal("expected non-empty generated states")
}
if stateA == stateB {
t.Fatal("expected generated states to be unique across calls")
}
authURL, err := provider.GetAuthURL("redirect-state")
if err != nil {
t.Fatalf("GetAuthURL failed: %v", err)
}
if authURL.State != "redirect-state" {
t.Fatalf("expected auth url state to be preserved, got %q", authURL.State)
}
if authURL.Redirect != provider.RedirectURI {
t.Fatalf("expected redirect uri to be preserved, got %q", authURL.Redirect)
}
if !strings.Contains(authURL.URL, "response_type=code") {
t.Fatalf("expected google auth url to request authorization code flow, got %q", authURL.URL)
}
}
func TestWeChatProviderGetAuthURLSupportsKnownTypes(t *testing.T) {
tests := []struct {
name string
oauthType string
expectedHost string
expectedPath string
}{
{
name: "web login",
oauthType: "web",
expectedHost: "open.weixin.qq.com",
expectedPath: "/connect/qrconnect",
},
{
name: "public account login",
oauthType: "mp",
expectedHost: "open.weixin.qq.com",
expectedPath: "/connect/oauth2/authorize",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
provider := NewWeChatProvider("wx-app-id", "wx-app-secret", tc.oauthType)
authURL, err := provider.GetAuthURL("https://admin.example.com/login/oauth/callback", "wechat-state")
if err != nil {
t.Fatalf("GetAuthURL failed: %v", err)
}
parsed, err := url.Parse(authURL.URL)
if err != nil {
t.Fatalf("parse auth url failed: %v", err)
}
if parsed.Host != tc.expectedHost {
t.Fatalf("expected host %q, got %q", tc.expectedHost, parsed.Host)
}
if parsed.Path != tc.expectedPath {
t.Fatalf("expected path %q, got %q", tc.expectedPath, parsed.Path)
}
if authURL.State != "wechat-state" {
t.Fatalf("expected state to be preserved, got %q", authURL.State)
}
})
}
}
func TestWeChatProviderRejectsUnsupportedOAuthType(t *testing.T) {
provider := NewWeChatProvider("wx-app-id", "wx-app-secret", "mini")
if _, err := provider.GetAuthURL("https://admin.example.com/login/oauth/callback", "state"); err == nil {
t.Fatal("expected unsupported oauth type error")
}
}