[dw-free] "Maintainer only" posting security in communities
[commit: http://hg.dwscoalition.org/dw-free/rev/e36a761d81b3]
http://bugs.dwscoalition.org/show_bug.cgi?id=1589
Add 'Maintainers' security option when posting entries to communities.
Patch by
afuna.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=1589
Add 'Maintainers' security option when posting entries to communities.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- bin/upgrading/en.dat
- cgi-bin/DW/Logic/LogItems.pm
- cgi-bin/LJ/Entry.pm
- cgi-bin/LJ/S2/DayPage.pm
- cgi-bin/LJ/S2/MonthPage.pm
- cgi-bin/LJ/Setting/MinSecurity.pm
- cgi-bin/LJ/Talk.pm
- cgi-bin/LJ/User.pm
- cgi-bin/ljhooks.pl
- cgi-bin/ljprotocol.pl
- cgi-bin/weblib.pl
- htdocs/js/entry.js
- htdocs/tools/endpoints/getsecurityoptions.bml
-------------------------------------------------------------------------------- diff -r dbaae7e52705 -r e36a761d81b3 bin/upgrading/en.dat --- a/bin/upgrading/en.dat Tue Nov 24 19:51:11 2009 +0000 +++ b/bin/upgrading/en.dat Tue Nov 24 20:03:33 2009 +0000 @@ -2751,6 +2751,8 @@ setting.minsecurity.option.select.friend setting.minsecurity.option.select.members=members +setting.minsecurity.option.select.admin=administrators + setting.minsecurity.option.select.private=just me (private) setting.minsecurity.option.select.public=everyone (public) diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/DW/Logic/LogItems.pm --- a/cgi-bin/DW/Logic/LogItems.pm Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/DW/Logic/LogItems.pm Tue Nov 24 20:03:33 2009 +0000 @@ -412,8 +412,11 @@ sub recent_items # decide what level of security the remote user can see my $secwhere = ""; - if ($userid == $remoteid || $args{'viewall'}) { + if ( $userid == $remoteid + || ( $remote && $remote->can_manage( $u ) ) + || $args{'viewall'} ) { # no extra where restrictions... user can see all their own stuff + # community administrators can also see everything in their comms # alternatively, if 'viewall' opt flag is set, security is off. } elsif ($mask) { # can see public or things with them in the mask diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/LJ/Entry.pm --- a/cgi-bin/LJ/Entry.pm Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/LJ/Entry.pm Tue Nov 24 20:03:33 2009 +0000 @@ -764,24 +764,34 @@ sub visible_to # owners can always see their own. return 1 if $userid == $remoteid; - # other people can't read private - return 0 if $self->{'security'} eq "private"; + # should be 'usemask' or 'private' security from here out, otherwise + # assume it's something new and return 0 + return 0 unless $self->{security} eq "usemask" || $self->{security} eq "private"; - # should be 'usemask' security from here out, otherwise - # assume it's something new and return 0 - return 0 unless $self->{'security'} eq "usemask"; - - # if it's usemask, we have to refuse non-personal journals, - # so we have to load the user return 0 unless $remote->is_individual; - # check if it's a community and they're a member - return 1 if $self->journal->is_community && + if ( $self->security eq "private" ) { + # other people can't read private on personal journals + return 0 if $self->journal->is_individual; + + # but community administrators can read private entries on communities + return 1 if $self->journal->is_community && $remote->can_manage( $self->journal ); + + # private entry on a community; we're not allowed to see this + return 0; + } + + if ( $self->security eq "usemask" ) { + # check if it's a community and they're a member + return 1 if $self->journal->is_community && $remote->member_of( $self->journal ); + + my $gmask = $self->journal->trustmask( $remote ); + my $allowed = (int($gmask) & int($self->{'allowmask'})); + return $allowed ? 1 : 0; # no need to return matching mask + } - my $gmask = $self->journal->trustmask( $remote ); - my $allowed = (int($gmask) & int($self->{'allowmask'})); - return $allowed ? 1 : 0; # no need to return matching mask + return 0; } # returns hashref of (kwid => tag) for tags on the entry @@ -1548,8 +1558,12 @@ sub get_log2_recent_user last unless $left; last if $notafter and $item->{'rlogtime'} > $notafter; next unless $remote || $item->{'security'} eq 'public'; - next if $item->{'security'} eq 'private' - and $item->{'journalid'} != $remote->{'userid'}; + + if ( $item->{security} eq 'private' and $item->{journalid} != $remote->{userid} ) { + my $ju = LJ::load_userid( $item->{journalid} ); + next unless $remote->can_manage( $ju ); + } + if ($item->{'security'} eq 'usemask') { next unless $remote->is_individual; my $permit = ($item->{'journalid'} == $remote->{'userid'}); diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/LJ/S2/DayPage.pm --- a/cgi-bin/LJ/S2/DayPage.pm Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/LJ/S2/DayPage.pm Tue Nov 24 20:03:33 2009 +0000 @@ -52,7 +52,7 @@ sub DayPage ( $viewall, $viewsome ) = $remote->view_priv_check( $u, $get->{viewall}, 'day' ); - if ( $viewall || $remote->equals( $u ) ) { + if ( $viewall || $remote->equals( $u ) || $remote->can_manage( $u ) ) { $secwhere = ""; # see everything } elsif ( $remote->is_individual ) { my $gmask = $u->is_community ? $remote->member_of( $u ) : $u->trustmask( $remote ); diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/LJ/S2/MonthPage.pm --- a/cgi-bin/LJ/S2/MonthPage.pm Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/LJ/S2/MonthPage.pm Tue Nov 24 20:03:33 2009 +0000 @@ -52,7 +52,7 @@ sub MonthPage ( $viewall, $viewsome ) = $remote->view_priv_check( $u, $get->{viewall}, 'month' ); - if ( $viewall || $remote->equals( $u ) ) { + if ( $viewall || $remote->equals( $u ) || $remote->can_manage( $u ) ) { $secwhere = ""; # see everything } elsif ( $remote->is_individual ) { my $gmask = $u->is_community ? $remote->member_of( $u ) : $u->trustmask( $remote ); diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/LJ/Setting/MinSecurity.pm --- a/cgi-bin/LJ/Setting/MinSecurity.pm Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/LJ/Setting/MinSecurity.pm Tue Nov 24 20:03:33 2009 +0000 @@ -30,9 +30,11 @@ sub option { my @options = ( "" => $class->ml('setting.minsecurity.option.select.public'), friends => $u->is_community ? $class->ml('setting.minsecurity.option.select.members') : $class->ml('setting.minsecurity.option.select.friends'), + private => $u->is_community ? + $class->ml( 'setting.minsecurity.option.select.admin' ) : + $class->ml( 'setting.minsecurity.option.select.private' ) ); - push @options, ( private => $class->ml('setting.minsecurity.option.select.private') ) - if $u->is_personal; + my $ret = "<label for='${key}minsecurity'>" . $class->ml('setting.minsecurity.option') . "</label> "; $ret .= LJ::html_select({ @@ -48,11 +50,7 @@ sub save { my ($class, $u, $args) = @_; my $val = $class->get_arg($args, "minsecurity"); - if ($u->is_community) { - $val = "" unless $val =~ /^(friends)$/; - } else { - $val = "" unless $val =~ /^(friends|private)$/; - } + $val = "" unless $val =~ /^(friends|private)$/; $u->set_prop( newpost_minsecurity => $val ); diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/LJ/Talk.pm --- a/cgi-bin/LJ/Talk.pm Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/LJ/Talk.pm Tue Nov 24 20:03:33 2009 +0000 @@ -258,7 +258,7 @@ sub check_viewable my $journalname = $journal->username; if (defined $remote) { - if ( $journal->is_community && ! $journal->is_closed_membership && $remote ) { + if ( $journal->is_community && ! $journal->is_closed_membership && $remote && $item->{security} ne "private" ) { return $err->( BML::ml( 'talk.error.notauthorised.comm.open', { aopts => "href='$LJ::SITEROOT/community/join?comm=$journalname'" } ) ); } elsif ( $journal->is_community && $journal->is_closed_membership ) { return $err->( BML::ml( 'talk.error.notauthorised.comm.closed' ) ); diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/LJ/User.pm --- a/cgi-bin/LJ/User.pm Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/LJ/User.pm Tue Nov 24 20:03:33 2009 +0000 @@ -7711,27 +7711,37 @@ sub can_view # owners can always see their own. return 1 if $userid == $remoteid; - # other people can't read private - return 0 if $item->{'security'} eq "private"; - - # should be 'usemask' security from here out, otherwise + # should be 'usemask' or 'private' security from here out, otherwise # assume it's something new and return 0 - return 0 unless $item->{'security'} eq "usemask"; - - # if it's usemask, we have to refuse non-personal journals, - # so we have to load the user + return 0 unless $item->{security} eq "usemask" || $item->{security} eq "private"; + return 0 unless $remote->is_individual; # this far down we have to load the user my $u = LJ::want_user( $userid ) or return 0; - # check if it's a community and they're a member - return 1 if $u->is_community && - $remote->member_of( $u ); - - # now load allowmask - my $allowed = ( $u->trustmask( $remoteid ) & int($item->{'allowmask'}) ); - return $allowed ? 1 : 0; # no need to return matching mask + if ( $item->{security} eq "private" ) { + # other people can't read private on personal journals + return 0 if $u->is_individual; + + # but community administrators can read private entries on communities + return 1 if $u->is_community && $remote->can_manage( $u ); + + # private entry on a community; we're not allowed to see this + return 0; + } + + if ( $item->{security} eq "usemask" ) { + # check if it's a community and they're a member + return 1 if $u->is_community && + $remote->member_of( $u ); + + # now load allowmask + my $allowed = ( $u->trustmask( $remoteid ) & int($item->{'allowmask'}) ); + return $allowed ? 1 : 0; # no need to return matching mask + } + + return 0; } @@ -8021,7 +8031,7 @@ sub get_daycounts "viewall", "calendar" ); } - if ( $remote->userid == $uid || $viewall ) { + if ( $remote->userid == $uid || $viewall || $remote->can_manage( $u ) ) { $secwhere = ""; # see everything $memkind = 'a'; # all } elsif ( $remote->is_individual ) { diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/ljhooks.pl --- a/cgi-bin/ljhooks.pl Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/ljhooks.pl Tue Nov 24 20:03:33 2009 +0000 @@ -112,12 +112,9 @@ register_setter("newpost_minsecurity", s $$err = "Illegal value. Must be 'public', 'access' (for personal journals), 'members' (for communities), or 'private'"; return 0; } - # Don't let commmunities be private or access-locked + # Don't let commmunities be access-locked if ( $u->is_community ) { - if ( $value eq "private" ) { - $$err = "newpost_minsecurity cannot be private for communities"; - return 0; - } elsif ( $value eq "access" ) { + if ( $value eq "access" ) { $$err = "newpost_minsecurity cannot be access-locked for communities (use 'members' instead)"; return 0; } diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/ljprotocol.pl --- a/cgi-bin/ljprotocol.pl Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/ljprotocol.pl Tue Nov 24 20:03:33 2009 +0000 @@ -40,10 +40,11 @@ my %e = ( # User Errors "100" => [ E_PERM, "Invalid username" ], "101" => [ E_PERM, "Invalid password" ], - "102" => [ E_PERM, "Can't use custom/private security on shared/community journals." ], + "102" => [ E_PERM, "Can't use custom security on community journals." ], "103" => [ E_PERM, "Poll error" ], "104" => [ E_TEMP, "Error adding one or more friends" ], "105" => [ E_PERM, "Challenge expired" ], + "106" => [ E_PERM, "Can only use administrator-locked security on community journals you manage." ], "150" => [ E_PERM, "Can't post as non-user" ], "151" => [ E_TEMP, "Banned from journal" ], "152" => [ E_PERM, "Can't make back-dated entries in non-personal journal." ], @@ -1184,11 +1185,16 @@ sub postevent my $qsecurity = $dbh->quote($security); - ### make sure user can't post with "custom/private security" on shared journals + ### make sure user can't post with "custom security" on communities return fail($err,102) - if ($ownerid != $posterid && # community post - ($req->{'security'} eq "private" || - ($req->{'security'} eq "usemask" && $qallowmask != 1 ))); + if $ownerid != $posterid && # community post + $req->{'security'} eq "usemask" && $qallowmask != 1; + + ## make sure user can't post with "private security" on communities they don't manage + return fail( $err, 106 ) + if $ownerid != $posterid && # community post + $req->{'security'} eq "private" && + ! $u->can_manage( $uowner ); # make sure this user isn't banned from posting here (if # this is a community journal) @@ -1632,11 +1638,16 @@ sub editevent return fail($err, 203, "Invalid friends group security set.") if $qallowmask > 1 && $qallowmask % 2; - ### make sure user can't change a post to "custom/private security" on shared journals + ### make sure user can't post with "custom security" on communities return fail($err,102) - if ($ownerid != $posterid && # community post - ($req->{'security'} eq "private" || - ($req->{'security'} eq "usemask" && $qallowmask != 1 ))); + if $ownerid != $posterid && # community post + $req->{'security'} eq "usemask" && $qallowmask != 1; + + ## make sure user can't post with "private security" on communities they don't manage + return fail( $err, 106 ) + if $ownerid != $posterid && # community post + $req->{'security'} eq "private" && + ! $u->can_manage( $uowner ); # make sure the new entry's under the char limit # NOTE: as in postevent, this requires $req->{event} to be binary data diff -r dbaae7e52705 -r e36a761d81b3 cgi-bin/weblib.pl --- a/cgi-bin/weblib.pl Tue Nov 24 19:51:11 2009 +0000 +++ b/cgi-bin/weblib.pl Tue Nov 24 20:03:33 2009 +0000 @@ -1828,6 +1828,7 @@ PREVIEW my $string_friends = LJ::ejs(BML::ml('label.security.accesslist')); my $string_friends_comm = LJ::ejs(BML::ml('label.security.members')); my $string_private = LJ::ejs(BML::ml('label.security.private2')); + my $string_admin = LJ::ejs( BML::ml( 'label.security.maintainers' ) ); my $string_custom = LJ::ejs(BML::ml('label.security.custom')); $out .= qq{ @@ -1836,12 +1837,15 @@ PREVIEW UpdateFormStrings.friends = "$string_friends"; UpdateFormStrings.friends_comm = "$string_friends_comm"; UpdateFormStrings.private = "$string_private"; - UpdateFormStrings.custom = "$string_custom";</script> + UpdateFormStrings.custom = "$string_custom"; + UpdateFormStrings.admin = "$string_admin";</script> }; + $$onload .= " setColumns();" if $remote; my @secs = ("public", $string_public, "friends", $is_comm ? $string_friends_comm : $string_friends); push @secs, ("private", $string_private) unless $is_comm; + push @secs, ( "private", $string_admin ) if $is_comm && $remote && $remote->can_manage( $usejournalu ); my ( @secopts, @trust_groups ); @trust_groups = $remote->trust_groups if $remote; diff -r dbaae7e52705 -r e36a761d81b3 htdocs/js/entry.js --- a/htdocs/js/entry.js Tue Nov 24 19:51:11 2009 +0000 +++ b/htdocs/js/entry.js Tue Nov 24 20:03:33 2009 +0000 @@ -412,6 +412,9 @@ function changeSecurityOptions(defaultjo if (data.ret['is_comm']) { $('security').options[0] = new Option(UpdateFormStrings.public, 'public'); $('security').options[1] = new Option(UpdateFormStrings.friends_comm, 'friends'); + if ( data.ret['can_manage'] ) { + $('security').options[2] = new Option(UpdateFormStrings.admin, 'private'); + } } else { $('security').options[0] = new Option(UpdateFormStrings.public, 'public'); $('security').options[1] = new Option(UpdateFormStrings.friends, 'friends'); diff -r dbaae7e52705 -r e36a761d81b3 htdocs/tools/endpoints/getsecurityoptions.bml --- a/htdocs/tools/endpoints/getsecurityoptions.bml Tue Nov 24 19:51:11 2009 +0000 +++ b/htdocs/tools/endpoints/getsecurityoptions.bml Tue Nov 24 20:03:33 2009 +0000 @@ -19,6 +19,7 @@ my %ret = ( is_comm => $u->is_comm ? 1 : 0, + can_manage => $remote && $remote->can_manage( $u ) ? 1 : 0, ); return JSON::objToJson({ ret => \%ret }) unless $remote && $remote->can_post_to($u); --------------------------------------------------------------------------------