lens @ b8b6d3037c524575f140650ac243c16df6a98a92

  1package sql
  2
  3import (
  4	"context"
  5
  6	"golang.org/x/crypto/bcrypt"
  7	"gorm.io/gorm"
  8
  9	"git.sr.ht/~gabrielgio/img/pkg/database/repository"
 10)
 11
 12type (
 13	User struct {
 14		gorm.Model
 15		Username string
 16		Name     string
 17		Password string
 18		IsAdmin  bool
 19		Path     string
 20	}
 21
 22	Users []*User
 23
 24	UserRepository struct {
 25		db *gorm.DB
 26	}
 27)
 28
 29var _ repository.UserRepository = &UserRepository{}
 30var _ repository.AuthRepository = &UserRepository{}
 31
 32func NewUserRepository(db *gorm.DB) *UserRepository {
 33	return &UserRepository{
 34		db: db,
 35	}
 36}
 37
 38func (self *User) ToModel() *repository.User {
 39	return &repository.User{
 40		ID:       self.Model.ID,
 41		Name:     self.Name,
 42		Username: self.Username,
 43		Path:     self.Path,
 44		IsAdmin:  self.IsAdmin,
 45	}
 46}
 47
 48func (self Users) ToModel() (users []*repository.User) {
 49	for _, user := range self {
 50		users = append(users, user.ToModel())
 51	}
 52	return
 53}
 54
 55// Testing function, will remove later
 56// TODO: remove later
 57func (self *UserRepository) EnsureAdmin(ctx context.Context) {
 58	var exists bool
 59	self.db.
 60		WithContext(ctx).
 61		Model(&User{}).
 62		Select("count(*) > 0").
 63		Where("username = ?", "admin").
 64		Find(&exists)
 65
 66	if !exists {
 67		hash, _ := bcrypt.GenerateFromPassword([]byte("admin"), bcrypt.MinCost)
 68		self.db.Save(&User{
 69			Username: "admin",
 70			Path:     "/",
 71			IsAdmin:  true,
 72			Password: string(hash),
 73		})
 74	}
 75}
 76
 77func (self *UserRepository) List(ctx context.Context) ([]*repository.User, error) {
 78	users := Users{}
 79	result := self.db.
 80		WithContext(ctx).
 81		Find(&users)
 82
 83	if result.Error != nil {
 84		return nil, result.Error
 85	}
 86
 87	return users.ToModel(), nil
 88}
 89
 90func (self *UserRepository) Get(ctx context.Context, id uint) (*repository.User, error) {
 91	var user = &repository.User{ID: id}
 92	result := self.db.
 93		WithContext(ctx).
 94		First(user)
 95
 96	if result.Error != nil {
 97		return nil, result.Error
 98	}
 99
100	return user, nil
101}
102
103func (self *UserRepository) GetIDByUsername(ctx context.Context, username string) (uint, error) {
104	userID := struct {
105		ID uint
106	}{}
107
108	result := self.db.
109		WithContext(ctx).
110		Model(&User{}).
111		Where("username = ?", username).
112		First(&userID)
113
114	if result.Error != nil {
115		return 0, result.Error
116	}
117
118	return userID.ID, nil
119}
120
121func (self *UserRepository) GetPassword(ctx context.Context, id uint) ([]byte, error) {
122	userPassword := struct {
123		Password []byte
124	}{}
125
126	result := self.db.
127		WithContext(ctx).
128		Model(&User{}).
129		Where("id = ?", id).
130		First(&userPassword)
131
132	if result.Error != nil {
133		return nil, result.Error
134	}
135
136	return userPassword.Password, nil
137}
138
139func (self *UserRepository) Create(ctx context.Context, createUser *repository.CreateUser) (uint, error) {
140	user := &User{
141		Username: createUser.Username,
142		Name:     createUser.Name,
143		Path:     createUser.Path,
144		Password: string(createUser.Password),
145	}
146
147	result := self.db.
148		WithContext(ctx).
149		Create(user)
150	if result.Error != nil {
151		return 0, result.Error
152	}
153
154	return user.Model.ID, nil
155}
156
157func (self *UserRepository) Update(ctx context.Context, id uint, update *repository.UpdateUser) error {
158	user := &User{
159		Model: gorm.Model{
160			ID: id,
161		},
162		Username: update.Username,
163		Name:     update.Name,
164	}
165
166	result := self.db.
167		WithContext(ctx).
168		Save(user)
169	if result.Error != nil {
170		return result.Error
171	}
172
173	return nil
174}
175
176func (self *UserRepository) Delete(ctx context.Context, id uint) error {
177	userID := struct {
178		ID uint
179	}{
180		ID: id,
181	}
182	result := self.db.
183		WithContext(ctx).
184		Delete(userID)
185	if result.Error != nil {
186		return result.Error
187	}
188	return nil
189}
190
191func (u *UserRepository) Any(ctx context.Context) (bool, error) {
192	var exists bool
193	result := u.db.
194		WithContext(ctx).
195		Model(&User{}).
196		Select("count(id) > 0").
197		Find(&exists)
198
199	if result.Error != nil {
200		return false, result.Error
201	}
202
203	return exists, nil
204}
205
206func (u *UserRepository) GetPathFromUserID(ctx context.Context, id uint) (string, error) {
207	var userPath string
208
209	result := u.db.
210		WithContext(ctx).
211		Model(&User{}).
212		Select("path").
213		Where("id = ?", id).
214		First(&userPath)
215
216	if result.Error != nil {
217		return "", result.Error
218	}
219
220	return userPath, nil
221}