package basic import ( "testing" "time" "github.com/golang/mock/gomock" "github.com/tinode/chat/server/auth" "github.com/tinode/chat/server/store" "github.com/tinode/chat/server/store/mock_store" "github.com/tinode/chat/server/store/types" "golang.org/x/crypto/bcrypt" ) func TestAuthenticateScopesLoginByTenant(t *testing.T) { ctrl := gomock.NewController(t) users := mock_store.NewMockUsersPersistenceInterface(ctrl) oldUsers := store.Users store.Users = users t.Cleanup(func() { store.Users = oldUsers ctrl.Finish() }) hash, err := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.MinCost) if err != nil { t.Fatal(err) } users.EXPECT().GetAuthByLogin(types.TenantID(7), "alice"). Return(types.Uid(70), auth.LevelAuth, hash, time.Time{}, nil) users.EXPECT().GetAuthByLogin(types.TenantID(8), "alice"). Return(types.Uid(80), auth.LevelAuth, hash, time.Time{}, nil) a := &authenticator{name: "basic", minLoginLength: defaultMinLoginLength, minPasswordLength: defaultMinPasswordLength} recA, _, err := a.Authenticate(auth.AuthContext{TenantID: 7}, []byte("alice:password")) if err != nil { t.Fatal(err) } recB, _, err := a.Authenticate(auth.AuthContext{TenantID: 8}, []byte("alice:password")) if err != nil { t.Fatal(err) } if recA.TenantID != 7 || recA.Uid != 70 || recB.TenantID != 8 || recB.Uid != 80 { t.Fatalf("unexpected records: A=%+v B=%+v", recA, recB) } } func TestAuthenticateRejectsMissingTenant(t *testing.T) { a := &authenticator{name: "basic", minLoginLength: defaultMinLoginLength, minPasswordLength: defaultMinPasswordLength} if _, _, err := a.Authenticate(auth.AuthContext{}, []byte("alice:password")); err != types.ErrMalformed { t.Fatalf("got %v, want %v", err, types.ErrMalformed) } } func TestCheckLoginPolicyAcceptsE164Phone(t *testing.T) { a := &authenticator{name: "basic", minLoginLength: defaultMinLoginLength, minPasswordLength: defaultMinPasswordLength} if err := a.checkLoginPolicy("+8615521120255"); err != nil { t.Fatalf("E.164 phone login rejected: %v", err) } } func TestAddRecordAcceptsE164PhoneLogin(t *testing.T) { ctrl := gomock.NewController(t) users := mock_store.NewMockUsersPersistenceInterface(ctrl) oldUsers := store.Users store.Users = users t.Cleanup(func() { store.Users = oldUsers ctrl.Finish() }) users.EXPECT().AddAuthRecord(types.TenantID(7), types.Uid(42), auth.LevelAuth, gomock.Any(), time.Time{}).Return(nil) a := &authenticator{name: "basic", addToTags: true, minLoginLength: defaultMinLoginLength, minPasswordLength: 6} rec, err := a.AddRecord(auth.AuthContext{TenantID: 7}, &auth.Rec{TenantID: 7, Uid: 42}, []byte("+8615521120255:123456")) if err != nil { t.Fatal(err) } if rec == nil || rec.AuthLevel != auth.LevelAuth || len(rec.Tags) != 1 || rec.Tags[0] != "basic:+8615521120255" { t.Fatalf("unexpected auth record: %#v", rec) } } func TestCheckLoginPolicyRejectsMalformedPhone(t *testing.T) { a := &authenticator{name: "basic", minLoginLength: defaultMinLoginLength, minPasswordLength: defaultMinPasswordLength} if err := a.checkLoginPolicy("+86-15521120255"); err != types.ErrPolicy { t.Fatalf("got %v, want %v", err, types.ErrPolicy) } }