lens @ 7a414da9a802d5eeee911b3536790a061e1d7503

  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		Password: string(createUser.Password),
144	}
145
146	result := self.db.
147		WithContext(ctx).
148		Create(user)
149	if result.Error != nil {
150		return 0, result.Error
151	}
152
153	return user.Model.ID, nil
154}
155
156func (self *UserRepository) Update(ctx context.Context, id uint, update *repository.UpdateUser) error {
157	user := &User{
158		Model: gorm.Model{
159			ID: id,
160		},
161		Username: update.Username,
162		Name:     update.Name,
163	}
164
165	result := self.db.
166		WithContext(ctx).
167		Save(user)
168	if result.Error != nil {
169		return result.Error
170	}
171
172	return nil
173}
174
175func (self *UserRepository) Delete(ctx context.Context, id uint) error {
176	userID := struct {
177		ID uint
178	}{
179		ID: id,
180	}
181	result := self.db.
182		WithContext(ctx).
183		Delete(userID)
184	if result.Error != nil {
185		return result.Error
186	}
187	return nil
188}
189
190func (u *UserRepository) Any(ctx context.Context) (bool, error) {
191	var exists bool
192	result := u.db.
193		WithContext(ctx).
194		Model(&User{}).
195		Select("count(id) > 0").
196		Find(&exists)
197
198	if result.Error != nil {
199		return false, result.Error
200	}
201
202	return exists, nil
203}