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] changelog2009-10-14 04:15 am

[dw-free] Site-wide search

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

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

Okay, journal search now lets you see all content you can see, not just
public posts. This required changing the search db structure again.

Patch by [staff profile] mark.

Files modified:
  • bin/worker/sphinx-copier
  • bin/worker/sphinx-search-gm
  • cgi-bin/LJ/User.pm
  • htdocs/search.bml
--------------------------------------------------------------------------------
diff -r da0e247843a5 -r eb5de5207217 bin/worker/sphinx-copier
--- a/bin/worker/sphinx-copier	Tue Oct 13 16:10:32 2009 +0000
+++ b/bin/worker/sphinx-copier	Wed Oct 14 04:14:57 2009 +0000
@@ -110,10 +110,16 @@ sub work {
         );
         die $dbfrom->errstr if $dbfrom->err;
 
+        # we need extra security bits for some metadata.  we have to do this this way because
+        # it makes it easier to later do searches on various combinations of things at the same
+        # time...  also, even though these are bits, we're not going to ever use them as actual bits.
+        my @extrabits;
+        push @extrabits, 101 if $row->{security} eq 'private';
+        push @extrabits, 102 if $row->{security} eq 'public';
+
         # have to do some more munging
-        $row->{is_public} = $row->{security} eq 'public' ? 1 : 0;
         $row->{edittime} = $db_times->{$jitemid};
-        $row->{allowmask} = join ',', LJ::bit_breakdown( $row->{allowmask} );
+        $row->{allowmask} = join ',', LJ::bit_breakdown( $row->{allowmask} ), @extrabits;
         $row->{allowpublic} = $u->include_in_global_search ? 1 : 0;
 
         # very important, the search engine can't index compressed crap...
@@ -127,10 +133,10 @@ sub work {
 
         # insert
         $dbto->do(
-            q{REPLACE INTO posts_raw (id, journal_id, jitemid, poster_id, is_public, security_bits, allow_global_search, date_posted,
+            q{REPLACE INTO posts_raw (id, journal_id, jitemid, poster_id, security_bits, allow_global_search, date_posted,
                                       title, data, revtime)
-              VALUES (NULL, ?, ?, ?, ?, ?, ?, UNIX_TIMESTAMP(?), ?, ?, ?)},
-            undef, map { $row->{$_} } qw/ journalid jitemid posterid is_public allowmask allowpublic eventtime subject event edittime /
+              VALUES (NULL, ?, ?, ?, ?, ?, UNIX_TIMESTAMP(?), ?, ?, ?)},
+            undef, map { $row->{$_} } qw/ journalid jitemid posterid allowmask allowpublic eventtime subject event edittime /
         );
         die $dbto->errstr if $dbto->err;
 
diff -r da0e247843a5 -r eb5de5207217 bin/worker/sphinx-search-gm
--- a/bin/worker/sphinx-search-gm	Tue Oct 13 16:10:32 2009 +0000
+++ b/bin/worker/sphinx-search-gm	Wed Oct 14 04:14:57 2009 +0000
@@ -34,9 +34,6 @@ sub sphinx_search {
     my $args = Storable::thaw( $job->arg ) || {};
     return undef unless $args->{query};
 
-    # a little sanity check, we don't currently allow a global search on non-public content
-    return undef if $args->{userid} == 0 && $args->{public} != 1;
-
     my $sx = Sphinx::Search->new();
     $sx->SetServer( @LJ::SPHINX_SEARCHD );
 
@@ -51,9 +48,14 @@ sub sphinx_search {
     $sx->SetFilter( 'allow_global_search', [ 1 ] )
         unless $args->{userid};
 
-    # further filter on public items or not
-    $sx->SetFilter( 'is_public', [ 1 ] )
-        if $args->{public};
+    # security filtering is a dangerous game.  basically, the caller tells us whether to
+    # ignore security or gives us a mask of bits to work with.  from that we intuit what
+    # security options to enable on our filters to Sphinx.
+    unless ( $args->{ignore_security} ) {
+        # allow public posts and anything the mask allows
+        my @bits = ( 102, LJ::bit_breakdown( $args->{allowmask} ) );
+        $sx->SetFilter( 'security_bits', \@bits );
+    }
 
     my $res = $sx->Query( $args->{query} );
     return undef unless $res;
diff -r da0e247843a5 -r eb5de5207217 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm	Tue Oct 13 16:10:32 2009 +0000
+++ b/cgi-bin/LJ/User.pm	Wed Oct 14 04:14:57 2009 +0000
@@ -1751,7 +1751,7 @@ sub allow_search_by {
     return 1 if $u->is_community || $u->equals( $by );
 
     # check the userprop for security access
-    my $whocan = $u->prop( 'opt_allowsearchby' );
+    my $whocan = $u->prop( 'opt_allowsearchby' ) || 'F';
     return 1 if $whocan eq 'A';
     return 1 if $whocan eq 'F' && $u->trusts( $by );
     return 1 if $whocan eq 'N' && $u->equals( $by );
diff -r da0e247843a5 -r eb5de5207217 htdocs/search.bml
--- a/htdocs/search.bml	Tue Oct 13 16:10:32 2009 +0000
+++ b/htdocs/search.bml	Wed Oct 14 04:14:57 2009 +0000
@@ -96,12 +96,26 @@ body<=
     return $error->( "Hey, that offset is nonsensical... :(" )
         if $offset < 0 || $offset > 1000;
 
-    # set a public only flag if this is not your journal or a community you are in
-    my $public = 1;
-    $public = 0 if $su && ( $remote->equals( $su ) || ( $su->is_community && $remote->member_of( $su ) ) );
+    # we have to set a few flags on what to search.  default to public and no bits.
+    my ( $ignore_security, $allowmask ) = ( 0, 0 );
+    if ( $su ) {
+        # if it's you, all posts, all bits
+        if ( $remote->equals( $su ) ) {
+            $ignore_security = 1;
+
+        # or a comm you're in ...
+        } elsif ( $su->is_community && $remote->member_of( $su ) ) {
+            $ignore_security = 1;
+
+        # otherwise, if they trust you, get the mask ...
+        } elsif ( $su->trusts( $remote ) ) {
+            $allowmask = $su->trustmask( $remote );
+        }
+    }
 
     # the arguments to the search (userid=0 implies global search)
-    my $args = { userid => $su ? $su->id : 0, query => $q, offset => $offset, public => $public };
+    my $args = { userid => $su ? $su->id : 0, query => $q, offset => $offset,
+                 ignore_security => $ignore_security, allowmask => $allowmask };
     my $arg = Storable::nfreeze( $args );
 
     # so we know that they're searching something valid, send to gearman
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org