Skip to content

Commit

Permalink
Address set_player_privs footgun
Browse files Browse the repository at this point in the history
  • Loading branch information
appgurueu committed Jan 21, 2024
1 parent 404a063 commit d5099b6
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
25 changes: 23 additions & 2 deletions builtin/game/auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,15 @@ core.builtin_auth_handler = {

core_auth.save(auth_entry)

-- Run grant callbacks
for priv, _ in pairs(privileges) do
for priv, value in pairs(privileges) do
-- Warnings for improper API usage
if value == false then
core.log('warning', "`false` value in `privs`, this is almost certainly a bug, "..
"granting a privilege rather than revoking it")
elseif value ~= true then
core.log('warning', "non-`true` in `privs` set")
end
-- Run grant callbacks
if not prev_privs[priv] then
core.run_priv_callbacks(name, priv, nil, "grant")
end
Expand Down Expand Up @@ -180,6 +187,20 @@ core.set_player_privs = auth_pass("set_privileges")
core.remove_player_auth = auth_pass("delete_auth")
core.auth_reload = auth_pass("reload")

function core.change_player_privs(name, changes)
local privs = core.get_player_privs(name)
for priv, change in pairs(changes) do
if change == true then
privs[priv] = true
elseif change == false then
privs[priv] = nil
else
core.log('warning', "non-bool value in `changes` table")
end
end
core.set_player_privs(name, privs)
end

local record_login = auth_pass("record_login")
core.register_on_joinplayer(function(player)
record_login(player:get_player_name())
Expand Down
20 changes: 16 additions & 4 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5837,8 +5837,20 @@ Authentication
* `name`: string; if omitted, all auth data should be considered modified
* `minetest.set_player_password(name, password_hash)`: Set password hash of
player `name`.
* `minetest.set_player_privs(name, {priv1=true,...})`: Set privileges of player
`name`.
* `minetest.set_player_privs(name, privs)`: Set privileges of player `name`.
* `privs` is a **set** of privileges:
A table where the keys are names of privileges and the values are `true`.
* Example: `minetest.set_player_privs("singleplayer", {interact = true, fly = true})`.
This **sets** the player privileges to `interact` and `fly`;
`singleplayer` will only have these two privileges afterwards.
* `minetest.change_player_privs(name, changes)`: Helper to grant or revoke privileges.
* `changes`: Table of changes to make.
A field `[privname] = true` grants a privilege,
whereas `[privname] = false` revokes a privilege.
* Example: `minetest.change_player_privs("singleplayer", {interact = true, fly = false})`
will grant singleplayer the `interact` privilege
and revoke singleplayer's `fly` privilege.
All other privileges will remain unchanged.
* `minetest.auth_reload()`
* See `reload()` in authentication handler definition

Expand Down Expand Up @@ -10714,8 +10726,8 @@ Used by `minetest.register_authentication_handler`.

set_privileges = function(name, privileges),
-- Set privileges of player `name`.
-- `privileges` is in table form, auth data should be created if not
-- present.
-- `privileges` is in table form: keys are privilege names, values are `true`;
-- auth data should be created if not present.

reload = function(),
-- Reload authentication data from the storage location.
Expand Down

0 comments on commit d5099b6

Please sign in to comment.