diff options
author | Yorhel <git@yorhel.nl> | 2020-04-15 11:53:38 +0200 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2020-04-15 11:53:40 +0200 |
commit | be5ee198129301d84912380ed8d1636ad32f68b3 (patch) | |
tree | d02840ee97c05818556f886e69bcc5783b44c229 /lib | |
parent | 5a3a446b0530632942c577edbf10e9c7c2fb6fa9 (diff) |
SQL: Split "perm" column into multiple booleans
This simplifies several actions and makes permission checks more
obvious. This is also yack shaving for another feature I've been
planning to add: boardmods should be able to set other users' "board"
permission, tagmods for tags, etc. So that partial user bans don't need
the full "usermod" permission.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/VNDB/DB/Users.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Util/Auth.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/Auth.pm | 27 | ||||
-rw-r--r-- | lib/VNWeb/Docs/Lib.pm | 11 | ||||
-rw-r--r-- | lib/VNWeb/Elm.pm | 1 | ||||
-rw-r--r-- | lib/VNWeb/User/Edit.pm | 26 |
6 files changed, 25 insertions, 44 deletions
diff --git a/lib/VNDB/DB/Users.pm b/lib/VNDB/DB/Users.pm index 2f7d8e5c..85654180 100644 --- a/lib/VNDB/DB/Users.pm +++ b/lib/VNDB/DB/Users.pm @@ -29,7 +29,7 @@ sub dbUserGet { ); my @select = ( - qw|id username c_votes c_changes c_tags hide_list|, + qw|id username c_votes c_changes c_tags|, VNWeb::DB::sql_user(), # XXX: This duplicates id and username, but updating all the code isn't going to be easy q|extract('epoch' from registered) as registered|, ); diff --git a/lib/VNDB/Util/Auth.pm b/lib/VNDB/Util/Auth.pm index 4394149f..b05c86f9 100644 --- a/lib/VNDB/Util/Auth.pm +++ b/lib/VNDB/Util/Auth.pm @@ -73,7 +73,7 @@ sub authInfo { # a certain action. sub authCan { my(undef, $act) = @_; - auth->perm() & auth->listPerms->{$act} + auth && auth->{user}{"perm_$act"} } diff --git a/lib/VNWeb/Auth.pm b/lib/VNWeb/Auth.pm index 82484397..08aa8a91 100644 --- a/lib/VNWeb/Auth.pm +++ b/lib/VNWeb/Auth.pm @@ -64,36 +64,20 @@ TUWF::set log_format => sub { use overload bool => sub { defined shift->{user}{user_id} }; sub uid { shift->{user}{user_id} } -sub perm { shift->{user}{perm}||0 } sub user { shift->{user} } sub token { shift->{token} } -# The 'perm' field is a bit field, with the following bits. -# The 'usermod' flag is hardcoded in sql/func.sql for the user_* functions. -# Flag 256 was used for 'affiliates', now also free. -my %perms = qw{ - board 1 - boardmod 2 - edit 4 - imgvote 8 - tag 16 - dbmod 32 - tagmod 64 - usermod 128 -}; - -sub defaultPerms { $perms{board} + $perms{edit} + $perms{tag} + $perms{imgvote} } -sub allPerms { my $i = 0; $i |= $_ for values %perms; $i } -sub listPerms { \%perms } +my @perms = qw/board boardmod edit imgvote tag dbmod tagmod usermod/; +sub listPerms { @perms } # Create a read-only accessor to check if the current user is authorized to # perform a particular action. -for my $perm (keys %perms) { +for my $perm (@perms) { no strict 'refs'; - *{ "perm".ucfirst($perm) } = sub { (shift->perm() & $perms{$perm}) > 0 } + *{ 'perm'.ucfirst($perm) } = sub { shift->{user}{"perm_$perm"} } } @@ -150,7 +134,8 @@ sub _load_session { my($self, $uid, $token_db) = @_; my $user = $uid ? tuwf->dbRowi( - 'SELECT perm, ', sql_user(), ' FROM users u + 'SELECT ', sql_user(), ',', sql_comma(map "perm_$_", @perms), ' + FROM users u WHERE id = ', \$uid, 'AND', sql_func(user_isvalidsession => 'id', sql_fromhex($token_db), \'web') ) : {}; diff --git a/lib/VNWeb/Docs/Lib.pm b/lib/VNWeb/Docs/Lib.pm index e6805d45..aeb4f172 100644 --- a/lib/VNWeb/Docs/Lib.pm +++ b/lib/VNWeb/Docs/Lib.pm @@ -5,16 +5,19 @@ use VNWeb::Prelude; our @EXPORT = qw/enrich_html/; +my @special_perms = qw/boardmod dbmod usermod tagmod/; + sub _moderators { - my $l = tuwf->dbAlli('SELECT id, username, perm FROM users WHERE (perm & ', \(auth->allPerms &~ auth->defaultPerms), ') > 0 ORDER BY id LIMIT 100'); - my @modperms = grep 0 == (auth->listPerms->{$_} & auth->defaultPerms), keys auth->listPerms->%*; + my $cols = sql_comma map "perm_$_", @special_perms; + my $where = sql_or map "perm_$_", @special_perms; + my $l = tuwf->dbAlli("SELECT id, username, $cols FROM users WHERE $where ORDER BY id LIMIT 100"); xml_string sub { dl_ sub { for my $u (@$l) { dt_ sub { a_ href => "/u$u->{id}", $u->{username} }; - dd_ auth->allPerms == ($u->{perm} & auth->allPerms) ? 'admin' - : join ', ', sort grep $u->{perm} & auth->listPerms->{$_}, @modperms; + dd_ @special_perms == grep($u->{"perm_$_"}, @special_perms) ? 'admin' + : join ', ', grep $u->{"perm_$_"}, @special_perms; } } } diff --git a/lib/VNWeb/Elm.pm b/lib/VNWeb/Elm.pm index 70871bdd..d6d8d862 100644 --- a/lib/VNWeb/Elm.pm +++ b/lib/VNWeb/Elm.pm @@ -351,7 +351,6 @@ sub write_types { $data .= def urlStatic => String => string config->{url_static}; $data .= def adminEMail => String => string config->{admin_email}; - $data .= def userPerms => 'List (Int, String)' => list map tuple(VNWeb::Auth::listPerms->{$_}, string $_), sort keys VNWeb::Auth::listPerms->%*; $data .= def skins => 'List (String, String)' => list map tuple(string $_, string tuwf->{skins}{$_}[0]), sort { tuwf->{skins}{$a}[0] cmp tuwf->{skins}{$b}[0] } keys tuwf->{skins}->%*; diff --git a/lib/VNWeb/User/Edit.pm b/lib/VNWeb/User/Edit.pm index bfd2e5f8..0153dfdb 100644 --- a/lib/VNWeb/User/Edit.pm +++ b/lib/VNWeb/User/Edit.pm @@ -6,7 +6,6 @@ use VNWeb::Prelude; my $FORM = form_compile in => { username => { username => 1 }, email => { email => 1 }, - perm => { uint => 1, func => sub { ($_[0] & ~auth->allPerms) == 0 } }, ign_votes => { anybool => 1 }, show_nsfw => { anybool => 1 }, traits_sexual => { anybool => 1 }, @@ -17,6 +16,7 @@ my $FORM = form_compile in => { spoilers => { uint => 1, range => [ 0, 2 ] }, skin => { enum => tuwf->{skins} }, customcss => { required => 0, default => '', maxlength => 2000 }, + map(+("perm_$_" => { anybool => 1 }), VNWeb::Auth::listPerms), nodistract_can => { anybool => 1 }, nodistract_noads => { anybool => 1 }, @@ -47,8 +47,9 @@ sub _getmail { } TUWF::get qr{/$RE{uid}/edit}, sub { + my $permcols = sql_comma map "perm_$_", auth->listPerms; my $u = tuwf->dbRowi(q{ - SELECT id, username, perm, ign_votes, show_nsfw, traits_sexual + SELECT id, username, ign_votes, show_nsfw, traits_sexual,}, $permcols, q{ , tags_all, tags_cont, tags_ero, tags_tech, spoilers, skin, customcss , nodistract_can, nodistract_noads, nodistract_nofancy, support_can, support_enabled, uniname_can, uniname, pubskin_can, pubskin_enabled FROM users WHERE id =}, \tuwf->capture('id') @@ -61,12 +62,6 @@ TUWF::get qr{/$RE{uid}/edit}, sub { $u->{password} = undef; $u->{skin} ||= config->{skin_default}; - # Let's not disclose this (though it's not hard to find out through other means) - if(!auth->permUsermod) { - $u->{ign_votes} = 0; - $u->{perm} = auth->defaultPerms; - } - my $title = $u->{id} == auth->uid ? 'My Account' : "Edit $u->{username}"; framework_ title => $title, type => 'u', dbobj => $u, tab => 'edit', sub { @@ -85,13 +80,18 @@ elm_api UserEdit => undef, $FORM, sub { return elm_Taken if $data->{uniname} && tuwf->dbVali('SELECT 1 FROM users WHERE id <>', \$data->{id}, 'AND username =', \lc($data->{uniname})); + my @setcols = qw/ + show_nsfw traits_sexual tags_all tags_cont tags_ero tags_tech spoilers skin customcss + nodistract_noads nodistract_nofancy support_enabled uniname pubskin_enabled + /; if(auth->permUsermod) { tuwf->dbExeci(update => users => set => { username => $data->{username}, ign_votes => $data->{ign_votes}, email_confirmed => 1, }, where => { id => $data->{id} }); - tuwf->dbExeci(select => sql_func user_setperm => \$data->{id}, \auth->uid, sql_fromhex(auth->token), \$data->{perm}); + tuwf->dbExeci(select => sql_func user_setperm_usermod => \$data->{id}, \auth->uid, sql_fromhex(auth->token), \$data->{perm_usermod}); + push @setcols, map "perm_$_", grep $_ ne 'usermod', auth->listPerms; } if($data->{password}) { @@ -136,13 +136,7 @@ elm_api UserEdit => undef, $FORM, sub { $data->{skin} = '' if $data->{skin} eq config->{skin_default}; $data->{uniname} = '' if $data->{uniname} eq $data->{username}; - tuwf->dbExeci('UPDATE users SET', { %{$data}{qw/ - show_nsfw traits_sexual tags_all tags_cont tags_ero tags_tech spoilers skin customcss - nodistract_noads nodistract_nofancy support_enabled uniname pubskin_enabled - /} }, - 'WHERE id =', \$data->{id} - ); - + tuwf->dbExeci('UPDATE users SET', { %{$data}{@setcols} }, 'WHERE id =', \$data->{id}); $ret->(); }; |