GoDoxy/internal/auth/userpass_test.go
yusing 7461344004 fix: json store marshaling, api handler
- code clean up
- uncomment and simplify api auth handler
- fix redirect url for frontend
- proper redirect
2025-04-24 04:47:42 +08:00

115 lines
2.5 KiB
Go

package auth
import (
"bytes"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
"time"
. "github.com/yusing/go-proxy/internal/utils/testing"
"golang.org/x/crypto/bcrypt"
)
func newMockUserPassAuth() *UserPassAuth {
return &UserPassAuth{
username: "username",
pwdHash: Must(bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost)),
secret: []byte("abcdefghijklmnopqrstuvwxyz"),
tokenTTL: time.Hour,
}
}
func TestUserPassValidateCredentials(t *testing.T) {
auth := newMockUserPassAuth()
err := auth.validatePassword("username", "password")
ExpectNoError(t, err)
err = auth.validatePassword("username", "wrong-password")
ExpectError(t, ErrInvalidPassword, err)
err = auth.validatePassword("wrong-username", "password")
ExpectError(t, ErrInvalidUsername, err)
}
func TestUserPassCheckToken(t *testing.T) {
auth := newMockUserPassAuth()
token, err := auth.NewToken()
ExpectNoError(t, err)
tests := []struct {
token string
wantErr bool
}{
{
token: token,
wantErr: false,
},
{
token: "invalid-token",
wantErr: true,
},
{
token: "",
wantErr: true,
},
}
for _, tt := range tests {
req := &http.Request{Header: http.Header{}}
if tt.token != "" {
req.Header.Set("Cookie", auth.TokenCookieName()+"="+tt.token)
}
err = auth.CheckToken(req)
if tt.wantErr {
ExpectTrue(t, err != nil)
} else {
ExpectNoError(t, err)
}
}
}
func TestUserPassLoginCallbackHandler(t *testing.T) {
type cred struct {
User string `json:"username"`
Pass string `json:"password"`
}
auth := newMockUserPassAuth()
tests := []struct {
creds cred
wantErr bool
}{
{
creds: cred{
User: "username",
Pass: "password",
},
wantErr: false,
},
{
creds: cred{
User: "username",
Pass: "wrong-password",
},
wantErr: true,
},
}
for _, tt := range tests {
w := httptest.NewRecorder()
req := &http.Request{
Host: "app.example.com",
Body: io.NopCloser(bytes.NewReader(Must(json.Marshal(tt.creds)))),
}
auth.LoginHandler(w, req)
if tt.wantErr {
ExpectEqual(t, w.Code, http.StatusUnauthorized)
} else {
setCookie := Must(http.ParseSetCookie(w.Header().Get("Set-Cookie")))
ExpectTrue(t, setCookie.Name == auth.TokenCookieName())
ExpectTrue(t, setCookie.Value != "")
ExpectEqual(t, setCookie.Domain, "example.com")
ExpectEqual(t, setCookie.Path, "/")
ExpectEqual(t, setCookie.SameSite, http.SameSiteLaxMode)
ExpectEqual(t, setCookie.HttpOnly, true)
ExpectEqual(t, w.Code, http.StatusOK)
}
}
}