mirror of
https://github.com/knadh/listmonk.git
synced 2024-11-10 09:02:36 +08:00
Add user profile based permission check in auth middleware.
This commit is contained in:
parent
6d1dabd0bf
commit
e865847b66
4 changed files with 32 additions and 2 deletions
|
@ -26,6 +26,8 @@ const (
|
|||
// UserKey is the key on which the User profile is set on echo handlers.
|
||||
UserKey = "auth_user"
|
||||
SessionKey = "auth_session"
|
||||
|
||||
SuperAdminRole = 1
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -236,6 +238,22 @@ func (o *Auth) Middleware(next echo.HandlerFunc) echo.HandlerFunc {
|
|||
|
||||
func (o *Auth) Perm(next echo.HandlerFunc, perm string) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
u, ok := c.Get(UserKey).(models.User)
|
||||
if !ok {
|
||||
c.Set(UserKey, echo.NewHTTPError(http.StatusForbidden, "invalid session"))
|
||||
return next(c)
|
||||
}
|
||||
|
||||
// If there's no permission set on the handler or if the current user is a super admin, do no checks.
|
||||
if perm == "" || u.RoleID == SuperAdminRole {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
// Check if the current handler's permission is in the user's permission map.
|
||||
if _, ok := u.PermissionsMap[perm]; !ok {
|
||||
return echo.NewHTTPError(http.StatusForbidden, fmt.Sprintf("permission denied (%s)", perm))
|
||||
}
|
||||
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,11 @@ func (c *Core) GetUser(id int, username, email string) (models.User, error) {
|
|||
out.PasswordLogin = true
|
||||
}
|
||||
|
||||
out.PermissionsMap = make(map[string]struct{})
|
||||
for _, p := range out.Permissions {
|
||||
out.PermissionsMap[p] = struct{}{}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
|
@ -141,5 +146,10 @@ func (c *Core) LoginUser(username, password string) (models.User, error) {
|
|||
c.i18n.Ts("globals.messages.errorFetching", "name", "{globals.terms.users}", "error", pqErrMsg(err)))
|
||||
}
|
||||
|
||||
out.PermissionsMap = make(map[string]struct{})
|
||||
for _, p := range out.Permissions {
|
||||
out.PermissionsMap[p] = struct{}{}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ type User struct {
|
|||
Status string `db:"status" json:"status"`
|
||||
Avatar null.String `db:"-" json:"avatar"`
|
||||
|
||||
PermissionsTbl map[string]struct{} `db:"-" json:"-"`
|
||||
PermissionsMap map[string]struct{} `db:"-" json:"-"`
|
||||
LoggedInAt null.Time `db:"loggedin_at" json:"loggedin_at"`
|
||||
|
||||
HasPassword bool `db:"-" json:"-"`
|
||||
|
|
|
@ -1083,7 +1083,9 @@ SELECT username, password FROM users WHERE status='enabled' AND type='api';
|
|||
|
||||
-- name: login-user
|
||||
WITH u AS (
|
||||
SELECT * FROM users WHERE username=$1 AND status != 'disabled' AND password_login = TRUE
|
||||
SELECT users.*, r.name as role_name, r.permissions FROM users
|
||||
LEFT JOIN user_roles r ON (r.id = users.role_id)
|
||||
WHERE username=$1 AND status != 'disabled' AND password_login = TRUE
|
||||
)
|
||||
SELECT * FROM u WHERE CRYPT($2, password) = password;
|
||||
|
||||
|
|
Loading…
Reference in a new issue