Skip to content

Commit 527b948

Browse files
committed
use idomatic GORM for user and permissions
1 parent d05bbe5 commit 527b948

File tree

2 files changed

+37
-77
lines changed

2 files changed

+37
-77
lines changed

backend/pkg/database/gorm_common.go

Lines changed: 29 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -193,35 +193,26 @@ func (gr *GormRepository) GetUsers(ctx context.Context) ([]models.User, error) {
193193
}
194194

195195
func (gr *GormRepository) GetUser(ctx context.Context, userID uuid.UUID) (*models.User, error) {
196-
var dbUser models.User
197196
var user models.User
198-
result := gr.GormClient.WithContext(ctx).First(&dbUser, userID)
197+
result := gr.GormClient.WithContext(ctx).
198+
Preload("UserPermissions").
199+
First(&user, userID)
199200
if result.Error != nil {
200201
return nil, result.Error
201202
}
202203

203-
user.ID = dbUser.ID
204-
user.FullName = dbUser.FullName
205-
user.Email = dbUser.Email
206-
user.Username = dbUser.Username
207-
user.Role = dbUser.Role
208-
209-
// Populate ACLs for the user
210-
var acls []models.UserPermission
211-
if err := gr.GormClient.WithContext(ctx).
212-
Where("user_id = ?", user.ID).
213-
Find(&acls).Error; err != nil {
214-
return nil, err
215-
}
204+
// Convert UserPermissions to the Permissions map
216205
user.Permissions = make(map[string]map[string]bool)
217-
218-
for _, acl := range acls {
219-
if _, exists := user.Permissions[acl.TargetUserID.String()]; !exists {
220-
user.Permissions[acl.TargetUserID.String()] = make(map[string]bool)
206+
for _, perm := range user.UserPermissions {
207+
if _, exists := user.Permissions[perm.TargetUserID.String()]; !exists {
208+
user.Permissions[perm.TargetUserID.String()] = make(map[string]bool)
221209
}
222-
user.Permissions[acl.TargetUserID.String()][string(acl.Permission)] = true
210+
user.Permissions[perm.TargetUserID.String()][string(perm.Permission)] = true
223211
}
224212

213+
// Clear sensitive fields
214+
user.Password = ""
215+
225216
return &user, nil
226217
}
227218

@@ -232,65 +223,33 @@ func (gr *GormRepository) UpdateUserAndPermissions(ctx context.Context, user mod
232223
if result.Error != nil {
233224
return result.Error
234225
}
235-
// Update fields on User
236-
updates := map[string]interface{}{
237-
"full_name": user.FullName,
238-
"username": user.Username,
239-
"email": user.Email,
240-
"role": user.Role,
241-
}
242-
result = gr.GormClient.WithContext(ctx).Model(dbUser).Updates(updates)
243-
if result.Error != nil {
244-
return result.Error
245-
}
246-
// Update User Permissions
247-
var existingPermissions []models.UserPermission
248-
if err := gr.GormClient.WithContext(ctx).
249-
Where("user_id = ?", user.ID).
250-
Find(&existingPermissions).Error; err != nil {
226+
227+
// Update only changed fields using Select
228+
if err := gr.GormClient.WithContext(ctx).Model(&dbUser).
229+
Select("full_name", "username", "email", "role").
230+
Updates(user).Error; err != nil {
251231
return err
252232
}
253-
for targetUserId, permissions := range user.Permissions {
233+
234+
// Convert permissions map to UserPermissions slice
235+
var newPermissions []models.UserPermission
236+
for targetUserID, permissions := range user.Permissions {
254237
for permission, value := range permissions {
255238
if !value {
256239
continue
257240
}
258-
// Check if the permission already exists
259-
exists := false
260-
for _, existingPermission := range existingPermissions {
261-
if existingPermission.TargetUserID.String() == targetUserId && string(existingPermission.Permission) == permission {
262-
exists = true
263-
break
264-
}
265-
}
266-
if !exists {
267-
// Add new permission
268-
p := models.UserPermission{
269-
UserID: user.ID,
270-
TargetUserID: uuid.Must(uuid.Parse(targetUserId)),
271-
Permission: pkg.Permission(permission),
272-
}
273-
err := gr.GormClient.WithContext(ctx).Create(&p).Error
274-
if err != nil {
275-
return err
276-
}
277-
}
241+
newPermissions = append(newPermissions, models.UserPermission{
242+
UserID: user.ID,
243+
TargetUserID: uuid.Must(uuid.Parse(targetUserID)),
244+
Permission: pkg.Permission(permission),
245+
})
278246
}
279247
}
280248

281-
// Remove permissions that are no longer in user.Permissions
282-
for _, existingPermission := range existingPermissions {
283-
targetUserId := existingPermission.TargetUserID.String()
284-
permission := string(existingPermission.Permission)
285-
286-
// Check if the permission still exists in the new user.Permissions
287-
if _, exists := user.Permissions[targetUserId]; !exists || !user.Permissions[targetUserId][permission] {
288-
// Permission no longer exists, so delete it
289-
err := gr.GormClient.WithContext(ctx).Delete(&existingPermission).Error
290-
if err != nil {
291-
return err
292-
}
293-
}
249+
// Replace all permissions in a single operation
250+
// This will automatically handle adding new permissions and removing old ones
251+
if err := gr.GormClient.WithContext(ctx).Model(&dbUser).Association("UserPermissions").Replace(newPermissions); err != nil {
252+
return err
294253
}
295254

296255
return nil

backend/pkg/models/user.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ import (
1010

1111
type User struct {
1212
ModelBase
13-
FullName string `json:"full_name"`
14-
Username string `json:"username" gorm:"unique"`
15-
Password string `json:"password"`
16-
Picture string `json:"picture"`
17-
Email string `json:"email"`
18-
Role pkg.UserRole `json:"role"`
19-
Permissions map[string]map[string]bool `json:"permissions" gorm:"-:all"`
13+
FullName string `json:"full_name"`
14+
Username string `json:"username" gorm:"unique"`
15+
Password string `json:"password"`
16+
Picture string `json:"picture"`
17+
Email string `json:"email"`
18+
Role pkg.UserRole `json:"role"`
19+
Permissions map[string]map[string]bool `json:"permissions" gorm:"-:all"`
20+
UserPermissions []UserPermission `json:"-" gorm:"foreignKey:UserID"`
2021
}
2122

2223
func (user *User) HashPassword(password string) error {

0 commit comments

Comments
 (0)