fix: google provider auth

This commit is contained in:
2026-04-07 13:36:43 +02:00
parent de3f2d1777
commit 2e645f3368
5 changed files with 141 additions and 18 deletions

View File

@@ -99,5 +99,5 @@ var columnMappingListUsers map[string]string = map[string]string{
"user_id": "users.id", "user_id": "users.id",
"email": "users.email", "email": "users.email",
"first_name": "users.first_name", "first_name": "users.first_name",
"second_name": "users.second_name", "last_name": "users.last_name",
} }

View File

@@ -9,7 +9,11 @@ import (
type UICustomerRepo interface { type UICustomerRepo interface {
Get(id uint) (*model.Customer, error) Get(id uint) (*model.Customer, error)
GetByEmail(email string) (*model.Customer, error)
GetByExternalProviderId(provider model.AuthProvider, id string) (*model.Customer, error)
Find(langId uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.UserInList], error) Find(langId uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.UserInList], error)
Save(customer *model.Customer) error
Create(customer *model.Customer) error
} }
type CustomerRepo struct{} type CustomerRepo struct{}
@@ -29,6 +33,30 @@ func (repo *CustomerRepo) Get(id uint) (*model.Customer, error) {
return &customer, err return &customer, err
} }
func (repo *CustomerRepo) GetByEmail(email string) (*model.Customer, error) {
var customer model.Customer
err := db.DB.
Preload("Role.Permissions").
Where("email = ?", email).
First(&customer).
Error
return &customer, err
}
func (repo *CustomerRepo) GetByExternalProviderId(provider model.AuthProvider, id string) (*model.Customer, error) {
var customer model.Customer
err := db.DB.
Preload("Role.Permissions").
Where("provider = ? AND provider_id = ?", provider, id).
First(&customer).
Error
return &customer, err
}
func (repo *CustomerRepo) Find(langId uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.UserInList], error) { func (repo *CustomerRepo) Find(langId uint, p find.Paging, filt *filters.FiltersList) (*find.Found[model.UserInList], error) {
found, err := find.Paginate[model.UserInList](langId, p, db.DB. found, err := find.Paginate[model.UserInList](langId, p, db.DB.
Table("b2b_customers AS users"). Table("b2b_customers AS users").
@@ -44,6 +72,59 @@ func (repo *CustomerRepo) Find(langId uint, p find.Paging, filt *filters.Filters
return &found, err return &found, err
} }
func (repo *CustomerRepo) Save(customer *model.Customer) error {
return db.DB.Save(customer).Error
}
func (repo *CustomerRepo) Create(customer *model.Customer) error {
return db.DB.Create(customer).Error
}
// func (repo *CustomerRepo) Search(
// customerId uint,
// partnerCode string,
// p find.Paging,
// filt *filters.FiltersList,
// search string,
// ) (found find.Found[model.UserInList], err error) {
// words := strings.Fields(search)
// if len(words) > 5 {
// words = words[:5]
// }
// query := ctx.DB().
// Model(&model.Customer{}).
// Select("customer.id AS id, customer.first_name as first_name, customer.last_name as last_name, customer.phone_number AS phone_number, customer.email AS email, count(distinct investment_plan_contract.id) as iiplan_purchases, count(distinct `order`.id) as single_purchases, entity.name as entity_name").
// Where("customer.id <> ?", customerId).
// Where("(customer.id IN (SELECT id FROM customer WHERE partner_code IN (WITH RECURSIVE partners AS (SELECT code AS dst FROM partner WHERE code = ? UNION SELECT code FROM partner JOIN partners ON partners.dst = partner.superior_code) SELECT dst FROM partners)) OR customer.recommender_code = ?)", partnerCode, partnerCode).
// Scopes(view.CustomerListQuery())
// var conditions []string
// var args []interface{}
// for _, word := range words {
// conditions = append(conditions, `
// (LOWER(first_name) LIKE ? OR
// LOWER(last_name) LIKE ? OR
// phone_number LIKE ? OR
// LOWER(email) LIKE ?)
// `)
// for i := 0; i < 4; i++ {
// args = append(args, "%"+strings.ToLower(word)+"%")
// }
// }
// finalQuery := strings.Join(conditions, " AND ")
// query = query.Where(finalQuery, args...).
// Scopes(filt.All()...)
// found, err = find.Paginate[V](ctx, p, query)
// return found, errs.Recorded(span, err)
// }
// func (repo *ListRepo) ListUsers(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.UserInList], error) { // func (repo *ListRepo) ListUsers(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.UserInList], error) {
// var list []model.UserInList // var list []model.UserInList
// var total int64 // var total int64

View File

@@ -0,0 +1,22 @@
package roleRepo
import (
"git.ma-al.com/goc_daniel/b2b/app/db"
"git.ma-al.com/goc_daniel/b2b/app/model"
)
type UIRolesRepo interface {
Get(id uint) (*model.Role, error)
}
type RolesRepo struct{}
func New() UIRolesRepo {
return &RolesRepo{}
}
func (r *RolesRepo) Get(id uint) (*model.Role, error) {
var role model.Role
err := db.DB.First(&role, id).Error
return &role, err
}

View File

@@ -11,6 +11,8 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/config" "git.ma-al.com/goc_daniel/b2b/app/config"
"git.ma-al.com/goc_daniel/b2b/app/db" "git.ma-al.com/goc_daniel/b2b/app/db"
"git.ma-al.com/goc_daniel/b2b/app/model" "git.ma-al.com/goc_daniel/b2b/app/model"
"git.ma-al.com/goc_daniel/b2b/app/repos/customerRepo"
roleRepo "git.ma-al.com/goc_daniel/b2b/app/repos/rolesRepo"
"git.ma-al.com/goc_daniel/b2b/app/service/emailService" "git.ma-al.com/goc_daniel/b2b/app/service/emailService"
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
@@ -38,6 +40,8 @@ type AuthService struct {
db *gorm.DB db *gorm.DB
config *config.AuthConfig config *config.AuthConfig
email *emailService.EmailService email *emailService.EmailService
customerRepo customerRepo.UICustomerRepo
roleRepo roleRepo.UIRolesRepo
} }
// NewAuthService creates a new AuthService instance // NewAuthService creates a new AuthService instance
@@ -46,6 +50,8 @@ func NewAuthService() *AuthService {
db: db.Get(), db: db.Get(),
config: &config.Get().Auth, config: &config.Get().Auth,
email: emailService.NewEmailService(), email: emailService.NewEmailService(),
customerRepo: customerRepo.New(),
roleRepo: roleRepo.New(),
} }
// Auto-migrate the refresh_tokens table // Auto-migrate the refresh_tokens table
if svc.db != nil { if svc.db != nil {

View File

@@ -108,26 +108,32 @@ func (s *AuthService) HandleGoogleCallback(code string) (*model.AuthResponse, st
// findOrCreateGoogleUser finds an existing user by Google provider ID or email, // findOrCreateGoogleUser finds an existing user by Google provider ID or email,
// or creates a new one. // or creates a new one.
func (s *AuthService) findOrCreateGoogleUser(info *view.GoogleUserInfo) (*model.Customer, error) { func (s *AuthService) findOrCreateGoogleUser(info *view.GoogleUserInfo) (*model.Customer, error) {
var user model.Customer var user *model.Customer
// Try to find by provider + provider_id // Try to find by provider + provider_id
err := s.db.Where("provider = ? AND provider_id = ?", model.ProviderGoogle, info.ID).First(&user).Error user, err := s.customerRepo.GetByExternalProviderId(model.ProviderGoogle, info.ID)
if err == nil { if err == nil {
// Update avatar in case it changed // Update avatar in case it changed
user.AvatarURL = info.Picture user.AvatarURL = info.Picture
s.db.Save(&user) err = s.customerRepo.Save(user)
return &user, nil if err != nil {
return nil, err
}
return user, nil
} }
// Try to find by email (user may have registered locally before) // Try to find by email (user may have registered locally before)
err = s.db.Where("email = ?", info.Email).First(&user).Error user, err = s.customerRepo.GetByEmail(info.Email)
if err == nil { if err == nil {
// Link Google provider to existing account // Link Google provider to existing account
user.Provider = model.ProviderGoogle user.Provider = model.ProviderGoogle
user.ProviderID = info.ID user.ProviderID = info.ID
user.AvatarURL = info.Picture user.AvatarURL = info.Picture
user.IsActive = true user.IsActive = true
s.db.Save(&user) err = s.customerRepo.Save(user)
if err != nil {
return nil, err
}
// If email has not been verified yet, send email to admin. // If email has not been verified yet, send email to admin.
if !user.EmailVerified { if !user.EmailVerified {
@@ -139,7 +145,7 @@ func (s *AuthService) findOrCreateGoogleUser(info *view.GoogleUserInfo) (*model.
} }
user.EmailVerified = true user.EmailVerified = true
return &user, nil return user, nil
} }
// Create new user // Create new user
@@ -148,6 +154,7 @@ func (s *AuthService) findOrCreateGoogleUser(info *view.GoogleUserInfo) (*model.
FirstName: info.GivenName, FirstName: info.GivenName,
LastName: info.FamilyName, LastName: info.FamilyName,
Provider: model.ProviderGoogle, Provider: model.ProviderGoogle,
RoleID: 1, // user
ProviderID: info.ID, ProviderID: info.ID,
AvatarURL: info.Picture, AvatarURL: info.Picture,
IsActive: true, IsActive: true,
@@ -156,7 +163,7 @@ func (s *AuthService) findOrCreateGoogleUser(info *view.GoogleUserInfo) (*model.
CountryID: 2, // default is England CountryID: 2, // default is England
} }
if err := s.db.Create(&newUser).Error; err != nil { if err := s.customerRepo.Create(&newUser); err != nil {
return nil, fmt.Errorf("failed to create user: %w", err) return nil, fmt.Errorf("failed to create user: %w", err)
} }
@@ -169,6 +176,13 @@ func (s *AuthService) findOrCreateGoogleUser(info *view.GoogleUserInfo) (*model.
} }
} }
var role *model.Role
role, err = s.roleRepo.Get(newUser.RoleID)
if err != nil {
return nil, err
}
newUser.Role = role
return &newUser, nil return &newUser, nil
} }