mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2010-05-02 05:48 am

[dw-free] new community setting: Entry's author and maintainers may add existing tags to an entry

[commit: http://hg.dwscoalition.org/dw-free/rev/be1ddf76b147]

http://bugs.dwscoalition.org/show_bug.cgi?id=1757

Add new setting that allows communities to say 'only the author of a post
and jocommunity admins can edit the tags in a post'.

This patch was pulled from the LiveJournal.com repository.

Patch by [personal profile] fu.

Files modified:
  • cgi-bin/LJ/Console/Command/TagPermissions.pm
  • cgi-bin/LJ/S2.pm
  • cgi-bin/LJ/Tags.pm
  • cgi-bin/LJ/Talk.pm
  • htdocs/edittags.bml
  • htdocs/manage/tags.bml
  • htdocs/manage/tags.bml.text
--------------------------------------------------------------------------------
diff -r f28dc2867880 -r be1ddf76b147 cgi-bin/LJ/Console/Command/TagPermissions.pm
--- a/cgi-bin/LJ/Console/Command/TagPermissions.pm	Sun May 02 05:42:16 2010 +0000
+++ b/cgi-bin/LJ/Console/Command/TagPermissions.pm	Sun May 02 05:48:26 2010 +0000
@@ -23,7 +23,7 @@ sub desc { "Set tagging permission level
 
 sub args_desc { [
                  'community' => "Optional; community to change permission levels for.",
-                 'add level' => "Accounts at this level can add existing tags to entries. Value is one of 'public', 'access' (for personal journals), 'members' (for communities), 'private', 'none', or a custom group name.",
+                 'add level' => "Accounts at this level can add existing tags to entries. Value is one of 'public', 'access' (for personal journals), 'members' (for communities), 'author_admin' (for communities only), 'private', 'none', or a custom group name.",
                  'control level' => "Accounts at this level can do everything: add, remove, and create new tags. Value is one of 'public', 'access' (for personal journals), 'members' (for communities), 'private', 'none', or a custom group name.",
                  ] }
 
@@ -65,7 +65,7 @@ sub execute {
     my $validate_level = sub {
         my $level = shift;
         return 'protected' if $level eq 'friends';
-        return $level if $level =~ /^(?:private|public|none|protected)$/;
+        return $level if $level =~ /^(?:private|public|none|protected|author_admin)$/;
         # can't use access for a community or members for an individual
         return undef if $level =~ /^(?:members|access)$/;
 
@@ -77,8 +77,12 @@ sub execute {
 
     $add = $validate_level->($add);
     $control = $validate_level->($control);
-    return $self->error("Levels must be one of: 'private', 'public', 'none', 'access' (for personal journals), 'members' (for communities), or the name of a custom group.")
+    return $self->error("Levels must be one of: 'private', 'public', 'none', 'access' (for personal journals), 'members' (for communities), 'author_admin' (for communities only), or the name of a custom group.")
         unless $add && $control;
+    return $self->error("Only <add level> can be 'author_admin'")
+        if $control eq 'author_admin';
+    return $self->error("'author_admin' level can be applied to communities only")
+        if $add eq 'author_admin' && ! $foru->is_community;
 
     $foru->set_prop('opt_tagpermissions', "$add,$control");
 
diff -r f28dc2867880 -r be1ddf76b147 cgi-bin/LJ/S2.pm
--- a/cgi-bin/LJ/S2.pm	Sun May 02 05:42:16 2010 +0000
+++ b/cgi-bin/LJ/S2.pm	Sun May 02 05:48:26 2010 +0000
@@ -3592,7 +3592,9 @@ sub _Entry__get_link
                             LJ::S2::Image("$LJ::IMGPREFIX/silk/entry/edit.png", 16, 16));
     }
     if ($key eq "edit_tags") {
-        return $null_link unless $remote && LJ::Tags::can_add_tags(LJ::load_user($journal), $remote);
+        my $entry = LJ::Entry->new( $journalu, ditemid => $this->{itemid} );
+        
+        return $null_link unless $remote && LJ::Tags::can_add_entry_tags( $remote, $entry );
         return LJ::S2::Link("$LJ::SITEROOT/edittags?journal=$journal&amp;itemid=$this->{'itemid'}",
                             $ctx->[S2::PROPS]->{"text_edit_tags"},
                             LJ::S2::Image("$LJ::IMGPREFIX/silk/entry/tag_edit.png", 16, 16));
diff -r f28dc2867880 -r be1ddf76b147 cgi-bin/LJ/Tags.pm
--- a/cgi-bin/LJ/Tags.pm	Sun May 02 05:42:16 2010 +0000
+++ b/cgi-bin/LJ/Tags.pm	Sun May 02 05:48:26 2010 +0000
@@ -482,6 +482,36 @@ sub can_add_tags {
            LJ::Tags::_remote_satisfies_permission($u, $remote, $perms->{control});
 }
 
+
+sub can_add_entry_tags {
+    return undef unless LJ::is_enabled( "tags" );
+
+    my ( $remote, $entry ) = @_;
+    $remote = LJ::want_user( $remote );
+
+    return undef unless $remote && $entry;
+    return undef unless $remote->is_personal;
+    return undef if $remote->is_banned( $entry->journal );
+
+    my $journal = $entry->journal;
+    my $perms = LJ::Tags::get_permission_levels( $journal );
+
+    # specific case: are we the author of this entry, or otherwise an admin of the journal?
+    if ( $perms->{add} eq 'author_admin' ) {
+        # is author
+        return 1 if $remote->equals( $entry->poster );
+
+        # is journal administrator
+        return $remote->can_manage( $journal );
+    }
+
+    # general case, see if the remote can add tags to the journal, in general
+    return 1 if $remote->can_add_tags_to( $journal );
+
+    # not allowed
+    return undef;
+}
+
 # <LJFUNC>
 # name: LJ::Tags::can_control_tags
 # class: tags
@@ -522,6 +552,12 @@ sub _remote_satisfies_permission {
         return $u->trusts_or_has_member( $remote );
     } elsif ($perm eq 'private') {
         return LJ::can_manage($remote, $u);
+    } elsif ( $perm eq 'author_admin' ) {
+        # this tests whether the remote can add tags for this journal in general
+        # when we don't have an entry object available to us (e.g., posting)
+        # Existing entries, checking per-entry author permissions, should use
+        # LJ::Tag::can_add_entry_tags
+        return $remote->can_manage( $u ) || $remote->member_of( $u );
     } elsif ($perm =~ /^group:(\d+)$/) {
         my $grpid = $1+0;
         return undef unless $grpid >= 1 && $grpid <= 60;
@@ -698,8 +734,9 @@ sub update_logtags {
     return undef unless $remote || $opts->{force};
 
     # get trust levels
+    my $entry = LJ::Entry->new( $u, jitemid => $jitemid );
     my $can_control = LJ::Tags::can_control_tags($u, $remote);
-    my $can_add = $can_control || LJ::Tags::can_add_tags($u, $remote);
+    my $can_add = $can_control || LJ::Tags::can_add_entry_tags( $remote, $entry );
 
     # bail out early if we can't do any actions
     return $err->( LJ::Lang::ml( 'taglib.error.access' ) )
diff -r f28dc2867880 -r be1ddf76b147 cgi-bin/LJ/Talk.pm
--- a/cgi-bin/LJ/Talk.pm	Sun May 02 05:42:16 2010 +0000
+++ b/cgi-bin/LJ/Talk.pm	Sun May 02 05:48:26 2010 +0000
@@ -146,7 +146,7 @@ sub link_bar
 
     # edit tags
     if ( LJ::is_enabled('tags') ) {
-        if (defined $remote && LJ::Tags::can_add_tags($u, $remote)) {
+        if ( defined $remote && LJ::Tags::can_add_entry_tags( $remote, $entry ) ) {
             push @linkele, $mlink->("$LJ::SITEROOT/edittags?${jargent}itemid=$itemid", "edittags");
         }
     }
diff -r f28dc2867880 -r be1ddf76b147 htdocs/edittags.bml
--- a/htdocs/edittags.bml	Sun May 02 05:42:16 2010 +0000
+++ b/htdocs/edittags.bml	Sun May 02 05:48:26 2010 +0000
@@ -116,7 +116,9 @@ body<=
 
     $ret .= "<tr><td class='l'>$ML{'.current'}</td>";
     $ret .= "<td class='sep'>";
-    if ( LJ::Tags::can_add_tags($u, $remote) ) {
+
+    my $can_add_entry_tags = LJ::Tags::can_add_entry_tags( $remote, LJ::Entry->new($u, ditemid => $ditemid ) );
+    if ( $can_add_entry_tags ) {
         $ret .= LJ::html_text(
             {
                 name  => 'edittags',
@@ -149,7 +151,7 @@ body<=
     }
 
     $ret .= "<br /><br />";
-    $ret .= "$ML{'.permissions.add.yes'}<br />" if LJ::Tags::can_add_tags($u, $remote);
+    $ret .= "$ML{'.permissions.add.yes'}<br />" if $can_add_entry_tags;
     $ret .= "$ML{'.permissions.control.yes'}<br />" if LJ::Tags::can_control_tags($u, $remote);
     $ret .= BML::ml('.view', { aopts => 'href="' . LJ::journal_base($u) . "/$ditemid.html" . '"' });
     $ret .= "</td></tr>";
diff -r f28dc2867880 -r be1ddf76b147 htdocs/manage/tags.bml
--- a/htdocs/manage/tags.bml	Sun May 02 05:42:16 2010 +0000
+++ b/htdocs/manage/tags.bml	Sun May 02 05:48:26 2010 +0000
@@ -113,7 +113,7 @@ HEAD
             my $control = $POST{"control_level"};
 
             $ret .= "<?errorbar $ML{'.error.invalidsettings'} errorbar?>"
-               unless $add =~ /^(?:private|public|protected|group:\d+)$/ &&
+               unless $add =~ /^(?:private|public|protected|author_admin|group:\d+)$/ &&
                $control =~ /^(?:private|public|protected|group:\d+)$/;
 
             $u->set_prop("opt_tagpermissions", "$add,$control");
@@ -350,6 +350,9 @@ HEAD
     } else {
         push @groups, ("protected", $ML{'.setting.members'});
         push @groups, ("private", $ML{'.setting.maintainers'});
+
+        push @groups, ( "author_admin", $ML{'.setting.author_admin'} )
+            if $u->is_community;
     }
 
     my @grouplist = $u->trust_groups;
diff -r f28dc2867880 -r be1ddf76b147 htdocs/manage/tags.bml.text
--- a/htdocs/manage/tags.bml.text	Sun May 02 05:42:16 2010 +0000
+++ b/htdocs/manage/tags.bml.text	Sun May 02 05:48:26 2010 +0000
@@ -55,6 +55,8 @@
 
 .none=You haven't created any tags yet.
 
+.setting.author_admin=Entry author and admininstrators
+
 .setting.desc.add=Who can add existing tags to entries?
 
 .setting.desc.control=Who can create new tags and add/remove tags from entries?
--------------------------------------------------------------------------------