Extension:Restrict access by category and group/with img auth support

From mediawiki.org

This version is identical to the one listed in the main extension (parent) page except for the additional of a single line at the end that revoke the read permission for all users (e.g. regardless of who they are visiting this page on this client session). This effectively extends the functionality of this extension to the img_auth.php script (if used) making direct access links to uploaded media files inaccessible as well.

Here is the part I updated:

	// In cases where the protected page is in the File namespace and we are protecting an uploaded file
	// "and" the wiki is configured to use "img_auth.php" --- We need to revoke the "read" permission as well
	// for all users (effectively just for this attempt) so that img_auth.php knows to deny access to the media.
	$wgGroupPermissions['*']['read'] = false;
	return false;

Here is the full code:

<?php

if ( !defined( 'MEDIAWIKI' ) ) {
	die( 'Not a valid entry point.' );
}

$wgExtensionCredits['parserhook'][] = array(
	'name' => 'Restrict access by category and group',
	'author' => 'Andrés Orencio Ramirez Perez (w/ mod by R.Evans)',
	'url' => 'https://www.mediawiki.org/wiki/Extension:Restrict_access_by_category_and_group',
	'description' => 'Allows to restrict access to pages by users groups and page categories (revokes read permission to support img_auth)',
	'version' => '2.0.1.1'
);

$wgHooks['userCan'][] = 'restrictAccessByCategoryAndGroup';

function restrictAccessByCategoryAndGroup( $title, $user, $action, $result ) {
	global $wgGroupPermissions;
	global $wgWhitelistRead;
	global $wgLang;
	global $wgHooks;
	global $wgContLang;
	global $wgWhitelistRead;
	global $wgVersion;

	//The Main Page, Login and Logout pages should always be accessible
	if ( $wgVersion >= '1.17' ) {
		$wgWhitelistRead[] = wfMessage( 'mainpage' )->plain();
	} else {
		$wgWhitelistRead[] = wfMsgForContent( 'mainpage' );
	}
        $wgWhitelistRead[] = SpecialPage::getTitleFor( 'Userlogin' )->getLocalUrl();
        $wgWhitelistRead[] = SpecialPage::getTitleFor( 'Userlogout' )->getLocalUrl();

	$validCategory = false;
	$groupExists = false;
	$pageHasCategories = false;
	$privateCategory = false;
	$privateCategoryTemp = false;
	$categoryNamespace = $wgLang->getNsText( NS_CATEGORY );
	$whitePage = true;

	//System categories
	$systemCategory = array();
	foreach ( array_change_key_case( $title->getParentCategories(), CASE_LOWER ) as $key => $value ) {
		$formatedKey = substr( $key, ( strpos( $key, ":" ) + 1 ) );
		$systemCategory[ $formatedKey ] = $value;
	}

	//Is this page a white page?
	if ( isset( $wgWhitelistRead[0] ) ) {
		$whitePage = in_array( $title, $wgWhitelistRead );
	}

	//If the page has no categories, it's public.
	if ( count( $title->getParentCategories() ) == 0 ) {
		$validCategory = true;
	} else {
		//For each system categories
		foreach ( $wgGroupPermissions as $key => $value ) {
			//If current system category is defined as private, then tmpCatP is true
			if ( isset( $wgGroupPermissions[ $key ]['private'] ) ) {
				$privateCategoryTemp = $wgGroupPermissions[ $key ]['private'];
			} else {
				$privateCategoryTemp = false;
			}
			//If current system category exist in the document category array ...
			if ( array_key_exists( strtolower( str_replace( " ", "_", $key ) ), $systemCategory ) ) {
				if ( $privateCategoryTemp and !$privateCategory ) {
					$privateCategory = true;
					$validCategory = false;
				}
				//We see that the user belongs to one of the groups (like of category)
				if ( in_array( $key, $user->getGroups() ) and ( !$privateCategory or ( $privateCategoryTemp and $privateCategory ) ) ) {
					$validCategory = true;
				}
				$groupExists = true;
			}
		}
		$pageHasCategories = count( $title->getParentCategories() ) > 0;
	}

	if ( !$pageHasCategories ) {
		return true;
	}
	if ( !$groupExists and !$whitePage ) {
		return true;
	}
	if ( ( $user->isLoggedIn() and $validCategory ) or $whitePage ) {
		return true;
	}
	// In cases where the protected page is in the File namespace and we are protecting an uploaded file
	// "and" the wiki is configured to use "img_auth.php" --- We need to revoke the "read" permission as well
	// for all users (effectively just for this attempt) so that img_auth.php knows to deny access to the media.
	$wgGroupPermissions['*']['read'] = false;
	return false;
}