Skip to content

Commit

Permalink
Separate get individual user and get all users queries.
Browse files Browse the repository at this point in the history
  • Loading branch information
knadh committed Oct 26, 2024
1 parent 87db0d5 commit 1e4b3a2
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 27 deletions.
4 changes: 3 additions & 1 deletion frontend/src/assets/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,9 @@ body.is-noscroll {
}
.modal .modal-card-foot button {
flex-grow: 1;
&.is-primary {
font-weight: bold;
}
}
.modal .modal-close.is-large {
display: none;
Expand All @@ -492,7 +495,6 @@ body.is-noscroll {
.button {
&.is-primary {
background: $primary;
font-weight: bold;

&:hover, &:active {
background: darken($primary, 15%);
Expand Down
44 changes: 21 additions & 23 deletions internal/core/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package core
import (
"database/sql"
"encoding/json"
"errors"
"net/http"
"strings"

"github.com/knadh/listmonk/internal/utils"
"github.com/knadh/listmonk/models"
Expand All @@ -14,21 +12,31 @@ import (
"gopkg.in/volatiletech/null.v6"
)

// GetUsers retrieves all users.
func (c *Core) GetUsers() ([]models.User, error) {
out, err := c.getUsers(0, "", "")
return out, err
out := []models.User{}
if err := c.q.GetUsers.Select(&out); err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.users}", "error", pqErrMsg(err)))
}

return c.formatUsers(out), nil
}

// GetUser retrieves a specific user based on any one given identifier.
func (c *Core) GetUser(id int, username, email string) (models.User, error) {
out, err := c.getUsers(id, username, strings.ToLower(email))
if err != nil {
return models.User{}, echo.NewHTTPError(http.StatusInternalServerError,
var out models.User
if err := c.q.GetUser.Get(&out, id, username, email); err != nil {
if err == sql.ErrNoRows {
return out, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.notFound", "name", "{globals.terms.user}"))

}

return out, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.users}", "error", pqErrMsg(err)))
}

return out[0], nil
return c.formatUsers([]models.User{out})[0], nil
}

// CreateUser creates a new user.
Expand Down Expand Up @@ -144,18 +152,8 @@ func (c *Core) LoginUser(username, password string) (models.User, error) {
return out, nil
}

func (c *Core) getUsers(id int, username, email string) ([]models.User, error) {
out := []models.User{}
if err := c.q.GetUsers.Select(&out, id, username, email); err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError,
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.users}", "error", pqErrMsg(err)))
}

if len(out) == 0 {
return nil, errors.New("user not found")
}

for n, u := range out {
func (c *Core) formatUsers(users []models.User) []models.User {
for n, u := range users {
u := u

if u.Password.String != "" {
Expand Down Expand Up @@ -207,8 +205,8 @@ func (c *Core) getUsers(id int, username, email string) ([]models.User, error) {
}
}

out[n] = u
users[n] = u
}

return out, nil
return users
}
1 change: 1 addition & 0 deletions models/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type Queries struct {
UpdateUserLogin *sqlx.Stmt `query:"update-user-login"`
DeleteUsers *sqlx.Stmt `query:"delete-users"`
GetUsers *sqlx.Stmt `query:"get-users"`
GetUser *sqlx.Stmt `query:"get-user"`
GetAPITokens *sqlx.Stmt `query:"get-api-tokens"`
LoginUser *sqlx.Stmt `query:"login-user"`

Expand Down
38 changes: 35 additions & 3 deletions queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1129,17 +1129,49 @@ FROM users
LEFT JOIN ur ON users.user_role_id = ur.id
LEFT JOIN lp ON users.list_role_id = lp.list_role_id
LEFT JOIN lr ON lp.list_role_id = lr.id
ORDER BY users.created_at;

-- name: get-user
WITH sel AS (
SELECT * FROM users
WHERE
(
CASE
-- either filter one row by id/username/text OR match all rows.
WHEN $1::INT != 0 THEN users.id = $1
WHEN $2::TEXT != '' THEN username = $2
WHEN $3::TEXT != '' THEN email = $3
ELSE TRUE
END
)
ORDER BY users.created_at;
)
SELECT
sel.*,
ur.id AS user_role_id,
ur.name AS user_role_name,
ur.permissions AS user_role_permissions,
lr.id AS list_role_id,
lr.name AS list_role_name,
lp.list_role_perms
FROM sel
LEFT JOIN roles ur ON sel.user_role_id = ur.id AND ur.type = 'user' AND ur.parent_id IS NULL
LEFT JOIN (
SELECT r.id, r.name, r.permissions, r.list_id, l.name AS list_name
FROM roles r
LEFT JOIN lists l ON r.list_id = l.id
WHERE r.type = 'list' AND r.parent_id IS NULL
) lr ON sel.list_role_id = lr.id
LEFT JOIN LATERAL (
SELECT JSONB_AGG(
JSONB_BUILD_OBJECT(
'id', COALESCE(cr.list_id, lr.list_id),
'name', COALESCE(cl.name, lr.list_name),
'permissions', COALESCE(cr.permissions, lr.permissions)
)
) AS list_role_perms
FROM roles cr
LEFT JOIN lists cl ON cr.list_id = cl.id
WHERE cr.parent_id = lr.id AND cr.type = 'list'
GROUP BY lr.id
) lp ON TRUE;


-- name: get-api-tokens
Expand Down

0 comments on commit 1e4b3a2

Please sign in to comment.