| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package auth
- import (
- "context"
- "strings"
- "testing"
- "time"
- )
- // fakeStore 是 Store 的内存实现,供中间件与业务逻辑的单测使用。
- type fakeStore struct {
- sessions map[string]Session // token_hash -> session
- tokens map[string]APIToken
- users map[string]User
- touchedSessions []string
- touchedTokens []string
- deletedSessions []string
- }
- func newFakeStore() *fakeStore {
- return &fakeStore{
- sessions: make(map[string]Session),
- tokens: make(map[string]APIToken),
- users: make(map[string]User),
- }
- }
- func (f *fakeStore) FindSessionByHash(_ context.Context, tokenHash string) (Session, error) {
- s, ok := f.sessions[tokenHash]
- if !ok {
- return Session{}, ErrNotFound
- }
- return s, nil
- }
- func (f *fakeStore) TouchSession(_ context.Context, id string, _ time.Time) error {
- f.touchedSessions = append(f.touchedSessions, id)
- return nil
- }
- func (f *fakeStore) DeleteSession(_ context.Context, id string) error {
- f.deletedSessions = append(f.deletedSessions, id)
- return nil
- }
- func (f *fakeStore) FindTokenByHash(_ context.Context, tokenHash string) (APIToken, error) {
- t, ok := f.tokens[tokenHash]
- if !ok {
- return APIToken{}, ErrNotFound
- }
- return t, nil
- }
- func (f *fakeStore) TouchToken(_ context.Context, id string, _ time.Time) error {
- f.touchedTokens = append(f.touchedTokens, id)
- return nil
- }
- func (f *fakeStore) GetUser(_ context.Context, id string) (User, error) {
- u, ok := f.users[id]
- if !ok {
- return User{}, ErrNotFound
- }
- return u, nil
- }
- var _ Store = (*fakeStore)(nil)
- // HashTokenForTest 暴露「剥离会话标记后再哈希」的行为,供中间件测试构造 key。
- func HashTokenForTest(plain string) string {
- base, _ := splitSessionToken(plain)
- return base
- }
- func TestHashTokenConsistency(t *testing.T) {
- // 相同输入必须得到相同哈希,用于按 token_hash 查库。
- if HashToken("abc") != HashToken("abc") {
- t.Error("同一输入的哈希应一致")
- }
- }
- func TestSplitPendingTokenEdgeCases(t *testing.T) {
- cases := []struct {
- in string
- token string
- trust bool
- }{
- {in: "haven_pend_xyz", token: "haven_pend_xyz", trust: false},
- {in: "haven_pend_xyz:1", token: "haven_pend_xyz", trust: true},
- {in: "haven_pend_xyz:0", token: "haven_pend_xyz:0", trust: false},
- {in: ":1", token: "", trust: true},
- {in: "", token: "", trust: false},
- }
- for _, tc := range cases {
- tok, trust := splitPendingToken(tc.in)
- if tok != tc.token || trust != tc.trust {
- t.Errorf("splitPendingToken(%q) = (%q, %v),期望 (%q, %v)",
- tc.in, tok, trust, tc.token, tc.trust)
- }
- }
- }
- func TestIdentityString(t *testing.T) {
- if got := Anonymous.String(); got != "anonymous" {
- t.Errorf("Anonymous.String() = %q", got)
- }
- if got := SessionUser.String(); got != "session" {
- t.Errorf("SessionUser.String() = %q", got)
- }
- if got := TokenUser.String(); got != "token" {
- t.Errorf("TokenUser.String() = %q", got)
- }
- }
- func TestIdentityIsLoggedIn(t *testing.T) {
- if (Identity{Kind: Anonymous}).IsLoggedIn() {
- t.Error("Anonymous 不应算已登录")
- }
- if !(Identity{Kind: SessionUser}).IsLoggedIn() {
- t.Error("SessionUser 应算已登录")
- }
- if !(Identity{Kind: TokenUser}).IsLoggedIn() {
- t.Error("TokenUser 应算已登录")
- }
- }
- func TestTruncatePrefix(t *testing.T) {
- if got := truncatePrefix("abc"); got != "abc" {
- t.Errorf("短于前缀长度的应原样返回,实际 %q", got)
- }
- if got := truncatePrefix("haven_ro_abcdefghij"); got != "haven_ro" {
- t.Errorf("应截取前 8 位,实际 %q", got)
- }
- if strings.HasPrefix(truncatePrefix("haven_ro_abcdefghij"), "haven_ro_") {
- t.Error("前 8 位不应包含 scope 后的随机串")
- }
- }
|