diff --git a/PBot/Capabilities.pm b/PBot/Capabilities.pm index f668e0b2..74667514 100644 --- a/PBot/Capabilities.pm +++ b/PBot/Capabilities.pm @@ -36,19 +36,10 @@ sub initialize { $self->{caps}->load; # 'cap' command registered in PBot.pm because $self->{pbot}->{commands} is not yet loaded. - # add some basic capabilities + # add some capabilities used in this file $self->add('can-modify-capabilities', undef, 1); $self->add('can-group-capabilities', undef, 1); $self->add('can-ungroup-capabilities', undef, 1); - - # add capabilites to admin capabilities group - $self->add('admin', 'chanop', 1); # add chanop capabilities group to admin group -- see ChanOpCommands.md - $self->add('admin', 'can-useradd', 1); - $self->add('admin', 'can-userdel', 1); - $self->add('admin', 'can-userset', 1); - $self->add('admin', 'can-userunset', 1); - $self->add('admin', 'can-mode', 1); - $self->add('admin', 'can-mode-any', 1); } sub has { diff --git a/PBot/ChanOpCommands.pm b/PBot/ChanOpCommands.pm index 7a539903..860e4ca3 100644 --- a/PBot/ChanOpCommands.pm +++ b/PBot/ChanOpCommands.pm @@ -61,7 +61,7 @@ sub initialize { } $self->{pbot}->{capabilities}->add('can-mode-any', 'can-mode', 1); - # create chanop capabilities group + # add to chanop capabilities group $self->{pbot}->{capabilities}->add('chanop', 'can-ban', 1); $self->{pbot}->{capabilities}->add('chanop', 'can-unban', 1); $self->{pbot}->{capabilities}->add('chanop', 'can-mute', 1); @@ -73,6 +73,11 @@ sub initialize { $self->{pbot}->{capabilities}->add('chanop', 'can-devoice', 1); $self->{pbot}->{capabilities}->add('chanop', 'can-invite', 1); + # add to admin capability group + $self->{pbot}->{capabilities}->add('admin', 'chanop', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-mode', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-mode-any', 1); + # allow users to use !unban * or !unmute * $self->{pbot}->{capabilities}->add('can-clear-bans', undef, 1); $self->{pbot}->{capabilities}->add('can-clear-mutes', undef, 1); @@ -297,11 +302,11 @@ sub mode { my $u = $self->{pbot}->{users}->loggedin($channel, "$nick!$user\@$host"); if ($mode eq 'v') { if (not $self->{pbot}->{capabilities}->userhas($u, 'can-voice-wildcard')) { - return "/msg $nick Using wildcards with `mode +v` requires the can-voice-wildcard capability, which your user account does not have."; + return "/msg $nick Using wildcards with `mode v` requires the can-voice-wildcard capability, which your user account does not have."; } } else { if (not $self->{pbot}->{capabilities}->userhas($u, 'can-op-wildcard')) { - return "/msg $nick Using wildcards with `mode +o` requires the can-op-wildcard capability, which your user account does not have."; + return "/msg $nick Using wildcards with `mode o` requires the can-op-wildcard capability, which your user account does not have."; } } diff --git a/PBot/Users.pm b/PBot/Users.pm index e040184d..5234dc41 100644 --- a/PBot/Users.pm +++ b/PBot/Users.pm @@ -40,7 +40,11 @@ sub initialize { $self->{pbot}->{commands}->register(sub { return $self->userunset(@_) }, "userunset", 1); $self->{pbot}->{commands}->register(sub { return $self->mycmd(@_) }, "my", 0); - $self->{pbot}->{event_dispatcher}->register_handler('irc.join', sub { $self->on_join(@_) }); + $self->{pbot}->{capabilities}->add('admin', 'can-useradd', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-userdel', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-userset', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-userunset', 1); + $self->{pbot}->{capabilities}->add('can-modify-admins', undef, 1); } sub on_join { @@ -93,7 +97,7 @@ sub add_user { password => $password }; - foreach my $cap (split /\s*,\s*/, $capabilities) { + foreach my $cap (split /\s*,\s*/, lc $capabilities) { next if $cap eq 'none'; $data->{$cap} = 1; } @@ -349,12 +353,15 @@ sub useradd { return "Your user account does not have the can-modify-capabilities capability. You cannot create user accounts with capabilities."; } - foreach my $cap (split /\s*,\s*/, $capabilities) { + foreach my $cap (split /\s*,\s*/, lc $capabilities) { next if $cap eq 'none'; return "There is no such capability $cap." if not $self->{pbot}->{capabilities}->exists($cap); if (not $self->{pbot}->{capabilities}->userhas($u, $cap)) { return "To set the $cap capability your user account must also have it."; } + if ($self->{pbot}->{capabilities}->has($cap, 'admin') and not $self->{pbot}->{capabilities}->userhas($u, 'can-modify-admins')) { + return "To set the $cap capability your user account must have the can-modify-admins capability."; + } } $self->{pbot}->{users}->add_user($name, $channel, $hostmask, $capabilities, $password); return "User added."; @@ -369,6 +376,17 @@ sub userdel { return "Usage: userdel "; } + my $u = $self->find_user($channel, "$nick!$user\@$host"); + my $t = $self->find_user($channel, $hostmask); + + if ($self->{pbot}->{capabilities}->userhas($t, 'botowner') and not $self->{pbot}->{capabilities}->userhas($u, 'botowner')) { + return "Only botowners may delete botowner user accounts."; + } + + if ($self->{pbot}->{capabilities}->userhas($t, 'admin') and not $self->{pbot}->{capabilities}->userhas($u, 'can-modify-admins')) { + return "To delete admin user accounts your user account must have the can-modify-admins capability."; + } + my ($found_channel, $found_hostmask) = $self->find_user_account($channel, $hostmask); $found_channel = $channel if not defined $found_channel; # let DualIndexHashObject disambiguate return $self->remove_user($found_channel, $found_hostmask); @@ -409,6 +427,10 @@ sub userset { } } + if (defined $value and $self->{pbot}->{capabilities}->userhas($target, 'admin') and not $self->{pbot}->{capabilities}->userhas($u, 'can-modify-admins')) { + return "To modify admin user accounts your user account must have the can-modify-admins capability."; + } + if ($self->{pbot}->{capabilities}->exists($key) and not $self->{pbot}->{capabilities}->userhas($u, $key)) { return "To set the $key capability your user account must also have it." unless $self->{pbot}->{capabilities}->userhas($u, 'botowner'); } @@ -433,7 +455,7 @@ sub userunset { return "Usage: userunset [channel] "; } - my $u = $self->find_admin($channel, "$nick!$user\@$host"); + my $u = $self->find_user($channel, "$nick!$user\@$host"); my $target = $self->find_user($channel, $hostmask); if (not $u) { @@ -455,6 +477,10 @@ sub userunset { } } + if (defined $key and $self->{pbot}->{capabilities}->userhas($target, 'admin') and not $self->{pbot}->{capabilities}->userhas($u, 'can-modify-admins')) { + return "To modify admin user accounts your user account must have the can-modify-admins capability."; + } + if (defined $key and $self->{pbot}->{capabilities}->exists($key) and not $self->{pbot}->{capabilities}->userhas($u, $key)) { return "To unset the $key capability your user account must also have it." unless $self->{pbot}->{capabilities}->userhas($u, 'botowner'); } @@ -500,17 +526,25 @@ sub mycmd { if (defined $key) { $key = lc $key; - - if (defined $value and not $self->{pbot}->{capabilities}->userhas($u, 'admin')) { - my @disallowed = qw/name autoop autovoice/; - if (grep { $_ eq $key } @disallowed) { - return "The $key metadata requires the admin capability to set, which your user account does not have."; + if (defined $value) { + if (not $self->{pbot}->{capabilities}->userhas($u, 'can-modify-capabilities')) { + if ($key =~ m/^can-/ or $self->{pbot}->{capabilities}->exists($key)) { + return "The $key metadata requires the can-modify-capabilities capability, which your user account does not have."; + } } - } - if (defined $value and not $self->{pbot}->{capabilities}->userhas($u, 'can-modify-capabilities')) { - if ($key =~ m/^can-/ or $self->{pbot}->{capabilities}->exists($key)) { - return "The $key metadata requires the can-modify-capabilities capability, which your user account does not have."; + if (not $self->{pbot}->{capabilities}->userhas($u, 'botowner')) { + my @disallowed = qw/can-modify-admins botowner can-modify-capabilities/; + if (grep { $_ eq $key } @disallowed) { + return "The $key metadata requires the botowner capability to set, which your user account does not have."; + } + } + + if (not $self->{pbot}->{capabilities}->userhas($u, 'admin')) { + my @disallowed = qw/name autoop autovoice/; + if (grep { $_ eq $key } @disallowed) { + return "The $key metadata requires the admin capability to set, which your user account does not have."; + } } } } else {