summaryrefslogtreecommitdiff
path: root/src/Whitelist_MediaWiki_Namespaces_with_$wgWhitelistRead.adoc
blob: 1bd597d0f64eaf6f13a9f663b642e34c97f0693d (plain)
    1 Whitelist MediaWiki Namespaces with $wgWhitelistRead
    2 ====================================================
    3 :author: Aaron Ball
    4 :email: nullspoon@iohq.net
    5 
    6 
    7 == {doctitle}
    8 
    9 MediaWiki is designed for the most part to be an open document repository. In
   10 most setups (presumably), everyone can read and only registered users can edit.
   11 However, permissions can't get much more granular than this. For my project at
   12 least, I would like to not just limit anonymous users from editing, I would
   13 like to selectively limit them from reading certain things.
   14 
   15 I looked around for quite some time until I came upon a variable you can set in
   16 your LocalSettings.php file: **$wgWhitelistRead**. Basically, this variable
   17 whitelists the pages specified in the array. The downside to this is you can't
   18 use wildcards or namespaces/categories. You must specify a single page per
   19 array value. This doesn't quite cut it for my needs. That being said, here's my
   20 solution (albeit rough).
   21 
   22 The end goal here looks like this...
   23 
   24 * All users are blocked from reading and writing all pages
   25 * Users in all groups are then given read access to the whitelisted namespaces
   26 * Finally, users in the specified groups have read and write access to all
   27   pages (save for the administration/sysop pages of course).
   28 
   29 
   30 [[limiting-all-access]]
   31 == Limiting All Access
   32 
   33 To do this, in your LocalSettings.php file, place the following four lines... 
   34 
   35 ----
   36 $wgGroupPermissions['*']['read'] = false;
   37 $wgGroupPermissions['*']['edit'] = false;
   38 $wgGroupPermissions['user']['read'] = false;
   39 $wgGroupPermissions['user']['edit'] = false;
   40 ----
   41 
   42 
   43 [[granting-sysop-access]]
   44 == Granting Sysop Access
   45 
   46 Once you have the lines in the last section in your config file, your entire
   47 wiki should be unavailable, even to sysop people (they are users after all). To
   48 give access back to your sysop folk, place the following two lines in your
   49 LocalSettings.php file
   50 
   51 ----
   52 $wgGroupPermissions['sysop']['read'] = true;
   53 $wgGroupPermissions['sysop']['edit'] = true;
   54 ----
   55 
   56 This will only grant access to your sysop authenticated users. If they're not
   57 already authenticated, they still can't get to the Special:UserLogin form
   58 (we'll get to that in just a few) to login. They may be sysops at heart, but
   59 hearts don't authenticate people without usernames and passwords.
   60 
   61 
   62 [[granting-individual-group-access]]
   63 == Granting Individual Group Access
   64 
   65 Now that our sysops have permissions, next we need a custom group so we can
   66 grant permissions to them. We'll call that group 'GreenTea' (yes, I'm drinking
   67 some green tea right now). To do that, let's throw another few lines in the
   68 LocalSettings.php file...
   69 
   70 ----
   71 $wgGroupPermissions['greentea'] =
   72 $wgGroupPermissions['user']; $wgGroupPermissions['greentea']['read'] =
   73 true; $wgGroupPermissions['greentea']['edit'] = true;
   74 ----
   75 
   76 
   77 [[granting-minimal-global-permissions]]
   78 == Granting Minimal Global Permissions
   79 
   80 Now that our group is set up, we need to whitelist the necessary and wanted
   81 pages for anonymous folk to log in and/or do their thing depending on what
   82 groups they are in. To do this, let's add yet another few lines to our
   83 LocalSettings.php file
   84 
   85 ----
   86 $wgWhitelistRead = array(
   87   'Main Page',
   88   'Special:Userlogin',
   89   'Special:UserLogout',
   90 );
   91 ----
   92 
   93 What we just did was whitelist the main page, the login page, and the logout
   94 page. This allows users to get in and out of your wiki, whether or not their
   95 permissions allow them access to anything. At this point, you can log in with
   96 your sysop user and put people into our previously created 'greentea' group.
   97 Once that's done, the greentea users should have full access to the entire
   98 wiki.
   99 
  100 I would like to note here that that this point, users outside of the greentea
  101 group will have the same permissions as anonymous/unauthenticated users. They
  102 cannot read or edit any pages other than the ones currently whitelisted.
  103 
  104 
  105 [[editing-mediawiki-to-whitelist-namespaces]]
  106 == Editing MediaWiki to Whitelist Namespaces
  107 
  108 This is the only part that's out of the ordinary here. We are going to edit
  109 actual MediaWiki code. The big downside to doing this is that if the MediaWiki
  110 instance is upgrade, it is highly likely that the changes made in this section
  111 will be overwritten. Thankfully though, the changes are very simple, so making
  112 them again shouldn't be a problem. They're so simple in fact, I think the
  113 MediaWiki folks might actually accept my code into their branch.
  114 
  115 To set up our MediaWiki instance so it handles regex whitelist statements, we
  116 need to edit the Title.php file in the includes directory.
  117 
  118 Firstly, we need to comment out the code that processes the whitelist variable.
  119 Head to around line 1870 in Title.php and comment out just the following lines
  120 
  121 ----
  122 //Check with and without underscores
  123 if ( in_array( $name, $wgWhitelistRead, true ) || in_array( $dbName, $wgWhitelistRead, true ) )
  124   return true;
  125 ----
  126 
  127 
  128 Now that those have been commented out, we need to add in the code that will
  129 process regex statements in the whitelist array. Below the lines you just
  130 commented out, add the following code... 
  131 
  132 ----
  133 foreach ( $wgWhitelistRead as $item ) 
  134   if ( preg_match( '/^'.$item.'$/', $name ) 
  135   || preg_match( '/^'.$dbName.'$/', $name ) ) return true;
  136 ----
  137 
  138 
  139 [[usage]]
  140 == Usage
  141 
  142 To use the changes we just put in place, all that needs to be done is edit the
  143 $wgWhitelistRead variable in LocalSettings.php again.
  144 
  145 Say, for example, that we have a 'HowTo' namespace ('HowTo:Drink Green Tea' for
  146 example) that we want everyone to be able to read that isn't in the greentea
  147 group (they have to learn somehow after all). All that needs to be done is a
  148 little regex...
  149 
  150 ----
  151 $wgWhitelistRead = array(
  152   'Main Page',
  153   'Special:Userlogin',
  154   'Special:UserLogout',
  155   'HowTo:.*',
  156 );
  157 ----
  158 
  159 That just whitelisted all pages inside the 'HowTo' namespace.
  160 
  161 
  162 [[a-bad-explanation-attempt]]
  163 == A Bad Explanation Attempt
  164 
  165 In case anyone who doesn't know is wondering why you put a *.** at the end of
  166 the HowTo namespace, here you go.
  167 
  168 In regular expressions, various symbols have different meanings. In this case,
  169 the period signifies any case letter, number, symbol, etc. That means that
  170 'HowTo:.' would match anything like 'HowTo:A', 'HowTo:3', 'HowTo:-', etc. It
  171 would however not match 'HowTo:A123'. Why? The period in regular expressions
  172 matches only one character. What we need is to say match any character any
  173 number of times after 'HowTo:'. For that we'll need the asterisk.
  174 
  175 The asterisk in regular expressions is what we call a quantifier. It doesn't
  176 represent a character so much as a quantity. In non regex terms, an asterisk
  177 means that the previous character in the regex string can be repeated zero or
  178 more times and still match. That means that the regular expression 'c*' would
  179 match nothing, 'c', 'cccc', 'cccccc', etc. It would however not match for
  180 example, 'b', '5', '12345a', etc. In our example, 'HowTo:.*', the period
  181 represents any character and it is followed by an asterisk, so that means that
  182 any article that starts with 'HowTo:' will match, no matter what the ending,
  183 even if it doesn't have one.
  184 
  185 Hopefully someone finds this post useful. If anyone has questions about *.**
  186 please ask them in the comments.
  187 
  188 
  189 // vim: set syntax=asciidoc:

Generated by cgit