From e02d212277f1307248a22b2bcc0ab6fcb34d8a5e Mon Sep 17 00:00:00 2001 From: yequari Date: Fri, 12 Dec 2025 18:18:36 -0700 Subject: [PATCH] Add some user controls --- internal/models/mocks/user.go | 25 ++++++++++++++++ internal/models/user.go | 34 ++++++++++++++++++++++ ui/views/admin.templ | 7 ++--- ui/views/admin_templ.go | 54 +++++++++++++++++++---------------- 4 files changed, 91 insertions(+), 29 deletions(-) diff --git a/internal/models/mocks/user.go b/internal/models/mocks/user.go index 25da0e3..c865e0f 100644 --- a/internal/models/mocks/user.go +++ b/internal/models/mocks/user.go @@ -25,6 +25,31 @@ type UserModel struct { Settings map[string]models.Setting } +func (m *UserModel) AddUserToGroup(userId int64, groupId models.UserGroupId) error { + //TODO implement me + panic("implement me") +} + +func (m *UserModel) BanUser(userId int64) error { + //TODO implement me + panic("implement me") +} + +func (m *UserModel) UpdateUser(u models.User) error { + //TODO implement me + panic("implement me") +} + +func (m *UserModel) UpdatePassword(userId int64, password string) error { + //TODO implement me + panic("implement me") +} + +func (m *UserModel) Delete(userId int64) error { + //TODO implement me + panic("implement me") +} + func (m *UserModel) InitializeSettingsMap() error { return nil } diff --git a/internal/models/user.go b/internal/models/user.go index f7d735c..6c38f9f 100644 --- a/internal/models/user.go +++ b/internal/models/user.go @@ -68,6 +68,9 @@ type UserModelInterface interface { GetNumberOfUsers() int AddUserToGroup(userId int64, groupId UserGroupId) error BanUser(userId int64) error + UpdateUser(u User) error + UpdatePassword(userId int64, password string) error + Delete(userId int64) error } func (m *UserModel) InitializeSettingsMap() error { @@ -475,6 +478,37 @@ func (m *UserModel) BanUser(userId int64) error { return nil } +func (m *UserModel) UpdateUser(u User) error { + stmt := `UPDATE users SET Email=?, Name=? WHERE Id=?` + _, err := m.DB.Exec(stmt, u.Email, u.Username, u.ID) + if err != nil { + return err + } + return nil +} + +func (m *UserModel) UpdatePassword(userId int64, password string) error { + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), 12) + if err != nil { + return err + } + stmt := `UPDATE users SET HashedPassword=? WHERE Id=?` + _, err = m.DB.Exec(stmt, hashedPassword, userId) + if err != nil { + return err + } + return nil +} + +func (m *UserModel) Delete(userId int64) error { + stmt := `UPDATE users SET Deleted=? WHERE Id=?` + _, err := m.DB.Exec(stmt, time.Now().UTC().Format(time.RFC3339), userId) + if err != nil { + return err + } + return nil +} + func (m *UserModel) addUserToGroup(tx *sql.Tx, userId int64, groupId UserGroupId) error { stmt := `INSERT INTO users_groups (UserId, GroupId) VALUES (?, ?)` _, err := tx.Exec(stmt, userId, groupId) diff --git a/ui/views/admin.templ b/ui/views/admin.templ index 10247cd..c1e8038 100644 --- a/ui/views/admin.templ +++ b/ui/views/admin.templ @@ -39,7 +39,6 @@ templ adminSidebar() { @@ -68,14 +67,14 @@ templ AdminPanelUsersView(title string, data CommonData, users []models.User) { Username Joined Email - for _, u := range users { + {{ url := fmt.Sprintf("/admin/users/%s", shortIdToSlug(u.ShortId)) }} { u.Username } { u.Created.Format(time.RFC3339) } { u.Email } + } - @@ -107,7 +106,7 @@ templ AdminPanelUserMgmtView(title string, data CommonData, user models.User) {

Groups

diff --git a/ui/views/admin_templ.go b/ui/views/admin_templ.go index 6bd303b..62ca8da 100644 --- a/ui/views/admin_templ.go +++ b/ui/views/admin_templ.go @@ -106,7 +106,7 @@ func adminSidebar() templ.Component { templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -162,7 +162,7 @@ func AdminPanelLandingView(title string, data CommonData) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 54, Col: 15} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 53, Col: 15} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -223,13 +223,17 @@ func AdminPanelUsersView(title string, data CommonData, users []models.User) tem if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
UsernameJoinedEmail
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, u := range users { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } url := fmt.Sprintf("/admin/users/%s", shortIdToSlug(u.ShortId)) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
UsernameJoinedEmail
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(u.Username) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 74, Col: 51} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 73, Col: 51} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var12 string templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(u.Created.Format(time.RFC3339)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 75, Col: 44} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 74, Col: 44} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var13 string templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(u.Email) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 76, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 75, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -329,7 +333,7 @@ func AdminPanelUserMgmtView(title string, data CommonData, user models.User) tem }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -337,69 +341,69 @@ func AdminPanelUserMgmtView(title string, data CommonData, user models.User) tem if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "

User Info

Username

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

User Info

Username

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var16 string templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(user.Username) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 95, Col: 24} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 94, Col: 24} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

Email

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "

Email

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var17 string templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(user.Email) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 99, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 98, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "

Joined

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

Joined

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var18 string templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(user.Created.Format(time.RFC3339)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 103, Col: 44} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 102, Col: 44} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

Groups

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "

Groups

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, g := range user.Groups { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d %s", g, getGroupName(g))) + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", getGroupName(g))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 110, Col: 53} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `ui/views/admin.templ`, Line: 109, Col: 47} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err }