fix: select support identity by IM tenant
Deploy olons-server production / deploy (push) Successful in 5m4s
Deploy olons-server production / deploy (push) Successful in 5m4s
This commit is contained in:
@@ -37,13 +37,14 @@ func (s *Store) CustomerServiceByID(ctx context.Context, tenantID, serviceID int
|
|||||||
return &row, err
|
return &row, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) MemberIMIdentity(ctx context.Context, tenantID, memberID int64) (*MemberIMIdentity, error) {
|
func (s *Store) MemberIMIdentityForTenant(ctx context.Context, tenantID, memberID int64, imTenantCode string) (*MemberIMIdentity, error) {
|
||||||
if s == nil || s.db == nil {
|
if s == nil || s.db == nil {
|
||||||
return nil, errors.New("store is unavailable")
|
return nil, errors.New("store is unavailable")
|
||||||
}
|
}
|
||||||
var row MemberIMIdentity
|
var row MemberIMIdentity
|
||||||
err := s.db.GetContext(ctx, &row, `SELECT id,tenant_id,member_id,im_tenant_code,im_user_id,im_username,im_password_cipher
|
err := s.db.GetContext(ctx, &row, `SELECT id,tenant_id,member_id,im_tenant_code,im_user_id,im_username,im_password_cipher
|
||||||
FROM hg_app_member_im_identity WHERE tenant_id=? AND member_id=? LIMIT 1`, tenantID, memberID)
|
FROM hg_app_member_im_identity WHERE tenant_id=? AND member_id=? AND im_tenant_code=? LIMIT 1`,
|
||||||
|
tenantID, memberID, imTenantCode)
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return nil, ErrResourceNotFound
|
return nil, ErrResourceNotFound
|
||||||
}
|
}
|
||||||
@@ -77,10 +78,10 @@ func (s *Store) SaveMemberIMIdentity(ctx context.Context, identity *MemberIMIden
|
|||||||
im_password_cipher=VALUES(im_password_cipher),sync_status=1,last_error='',updated_at=UTC_TIMESTAMP(3)`,
|
im_password_cipher=VALUES(im_password_cipher),sync_status=1,last_error='',updated_at=UTC_TIMESTAMP(3)`,
|
||||||
identity.TenantID, identity.MemberID, identity.IMTenantCode, identity.IMUserID, identity.IMUsername, identity.IMPasswordCipher)
|
identity.TenantID, identity.MemberID, identity.IMTenantCode, identity.IMUserID, identity.IMUsername, identity.IMPasswordCipher)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return s.MemberIMIdentity(ctx, identity.TenantID, identity.MemberID)
|
return s.MemberIMIdentityForTenant(ctx, identity.TenantID, identity.MemberID, identity.IMTenantCode)
|
||||||
}
|
}
|
||||||
// A concurrent request may have completed the same deterministic mapping.
|
// A concurrent request may have completed the same deterministic mapping.
|
||||||
existing, findErr := s.MemberIMIdentity(ctx, identity.TenantID, identity.MemberID)
|
existing, findErr := s.MemberIMIdentityForTenant(ctx, identity.TenantID, identity.MemberID, identity.IMTenantCode)
|
||||||
if findErr == nil {
|
if findErr == nil {
|
||||||
return existing, nil
|
return existing, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
|
|
||||||
type Repository interface {
|
type Repository interface {
|
||||||
CustomerServiceByID(context.Context, int64, int64) (*store.CustomerService, error)
|
CustomerServiceByID(context.Context, int64, int64) (*store.CustomerService, error)
|
||||||
MemberIMIdentity(context.Context, int64, int64) (*store.MemberIMIdentity, error)
|
MemberIMIdentityForTenant(context.Context, int64, int64, string) (*store.MemberIMIdentity, error)
|
||||||
MemberIMProfile(context.Context, int64, int64) (*store.MemberIMProfile, error)
|
MemberIMProfile(context.Context, int64, int64) (*store.MemberIMProfile, error)
|
||||||
SaveMemberIMIdentity(context.Context, *store.MemberIMIdentity) (*store.MemberIMIdentity, error)
|
SaveMemberIMIdentity(context.Context, *store.MemberIMIdentity) (*store.MemberIMIdentity, error)
|
||||||
}
|
}
|
||||||
@@ -188,14 +188,8 @@ func (s *Service) OpenSession(ctx context.Context, tenantID, memberID, serviceID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) ensureIdentity(ctx context.Context, tenantID, memberID int64, imTenantCode string) (*store.MemberIMIdentity, error) {
|
func (s *Service) ensureIdentity(ctx context.Context, tenantID, memberID int64, imTenantCode string) (*store.MemberIMIdentity, error) {
|
||||||
identity, err := s.repository.MemberIMIdentity(ctx, tenantID, memberID)
|
identity, err := s.repository.MemberIMIdentityForTenant(ctx, tenantID, memberID, imTenantCode)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if !strings.EqualFold(identity.IMTenantCode, imTenantCode) {
|
|
||||||
// A tenant switch creates a distinct IM user. Keep the old tenant's IM
|
|
||||||
// account intact, but replace this member's local mapping with a newly
|
|
||||||
// provisioned account in the active tenant.
|
|
||||||
return s.createIdentity(ctx, tenantID, memberID, imTenantCode)
|
|
||||||
}
|
|
||||||
if identity.IMUserID == "" || identity.IMUsername == "" {
|
if identity.IMUserID == "" || identity.IMUsername == "" {
|
||||||
return nil, ErrIMUnavailable
|
return nil, ErrIMUnavailable
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type repositoryStub struct {
|
type repositoryStub struct {
|
||||||
agent *store.CustomerService
|
agent *store.CustomerService
|
||||||
identity *store.MemberIMIdentity
|
identity *store.MemberIMIdentity
|
||||||
profile *store.MemberIMProfile
|
profile *store.MemberIMProfile
|
||||||
|
requestedIMTenantCode string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *repositoryStub) CustomerServiceByID(context.Context, int64, int64) (*store.CustomerService, error) {
|
func (r *repositoryStub) CustomerServiceByID(context.Context, int64, int64) (*store.CustomerService, error) {
|
||||||
return r.agent, nil
|
return r.agent, nil
|
||||||
}
|
}
|
||||||
func (r *repositoryStub) MemberIMIdentity(context.Context, int64, int64) (*store.MemberIMIdentity, error) {
|
func (r *repositoryStub) MemberIMIdentityForTenant(_ context.Context, _, _ int64, imTenantCode string) (*store.MemberIMIdentity, error) {
|
||||||
|
r.requestedIMTenantCode = imTenantCode
|
||||||
|
if r.identity == nil || !strings.EqualFold(r.identity.IMTenantCode, imTenantCode) {
|
||||||
|
return nil, store.ErrResourceNotFound
|
||||||
|
}
|
||||||
return r.identity, nil
|
return r.identity, nil
|
||||||
}
|
}
|
||||||
func (r *repositoryStub) MemberIMProfile(context.Context, int64, int64) (*store.MemberIMProfile, error) {
|
func (r *repositoryStub) MemberIMProfile(context.Context, int64, int64) (*store.MemberIMProfile, error) {
|
||||||
@@ -207,3 +212,22 @@ func TestEnsureIdentityReprovisionsMemberWhenIMTenantChanges(t *testing.T) {
|
|||||||
t.Fatalf("provisioning login attempts = %d, want 1", im.loginAttempts)
|
t.Fatalf("provisioning login attempts = %d, want 1", im.loginAttempts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnsureIdentityQueriesTheActiveIMTenantMapping(t *testing.T) {
|
||||||
|
repository := &repositoryStub{
|
||||||
|
identity: &store.MemberIMIdentity{TenantID: 0, MemberID: 9, IMTenantCode: "allrich", IMUserID: "usr_old", IMUsername: "olduser"},
|
||||||
|
profile: &store.MemberIMProfile{MemberID: 9, Username: "member01"},
|
||||||
|
}
|
||||||
|
im := &imStub{}
|
||||||
|
service := New(repository, im, config.AuthConfig{FinanceMasterKey: strings.Repeat("k", 32)})
|
||||||
|
identity, err := service.ensureIdentity(context.Background(), 0, 9, "default")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if repository.requestedIMTenantCode != "default" {
|
||||||
|
t.Fatalf("queried IM tenant = %q, want default", repository.requestedIMTenantCode)
|
||||||
|
}
|
||||||
|
if identity.IMTenantCode != "default" {
|
||||||
|
t.Fatalf("identity tenant = %q, want default", identity.IMTenantCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user