jenkins-bot has submitted this change and it was merged.

Change subject: Add feature to restrict E-Maildomains
......................................................................


Add feature to restrict E-Maildomains

Enable the restriction of access via GoogleLogin to allowed E-Maildomains.
Introducing $wgGLAllowedDomains as config array in LocalSettings.php
to specify those allowed E-Maildomains.

With $wgGLAllowedDomainsStrict in LocalSettings.php can configured, if
the domain must exactly match (test.example.com don't macth example.com if
activated).

Added configuration variables into GoogleLogin.php with short explanation
and a default value.

Bug: 67220
Change-Id: I00b9cb9b844d5fbebe3bcb12f101d91ff609014c
---
M .gitignore
M GoogleLogin.php
M SpecialGoogleLogin.php
A cache/README
M i18n/de.json
M i18n/en.json
M i18n/qqq.json
7 files changed, 211 insertions(+), 23 deletions(-)

Approvals:
  Florianschmidtwelzow: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/.gitignore b/.gitignore
index 5664cb5..09f6347 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 vendor/*
 composer.phar
+cache/*
\ No newline at end of file
diff --git a/GoogleLogin.php b/GoogleLogin.php
index 52a62dc..532a235 100644
--- a/GoogleLogin.php
+++ b/GoogleLogin.php
@@ -53,3 +53,35 @@
        $wgHooks['UserLogoutComplete'][] = 
'GoogleLoginHooks::onUserLogoutComplete';
        $wgHooks['LoadExtensionSchemaUpdates'][] = 
'GoogleLoginHooks::onLoadExtensionSchemaUpdates';
        $wgHooks['UserLoginForm'][] = 'GoogleLoginHooks::onUserLoginForm';
+
+       // Configuration settings defaults
+
+       /**
+        * The Secret key of Google developer console
+        */
+       $wgGLSecret = '';
+
+       /**
+        * The App ID of the web application to use for GoogleLogin
+        */
+       $wgGLAppId = '';
+
+       /**
+        * Which domains are allowed to login (or create/merge an account) with 
GoogleLogin
+        * default: empty string -> all domains allowed
+        * to allow special domains, create an array with all allowed domains, 
example:
+        * array( 'example.com' );
+        */
+       $wgGLAllowedDomains = '';
+
+       /**
+        * If $wgGoogleAllowedDomains restrict to specified domains, use strict 
mode? Means:
+        * Only the exact specified domains are allowed, e.g. if 
test.example.com is allowed and strict
+        * mode is enabled, example.com isn't allowed (if strict mode is of, it 
is allowed)
+        */
+       $wgGLAllowedDomainsStrict = false;
+
+       /**
+        * If the user creates an account via GoogleLogin, show this as a 
reason in log?
+        */
+       $wgGLShowCreateReason = false;
diff --git a/SpecialGoogleLogin.php b/SpecialGoogleLogin.php
index 218da19..cdbefe4 100644
--- a/SpecialGoogleLogin.php
+++ b/SpecialGoogleLogin.php
@@ -124,29 +124,180 @@
                        $request = $this->getRequest();
                        $user = $this->getUser();
                        $googleIdExists = $db->GoogleIdExists( $userInfo['id'] 
);
-                       if ( !$googleIdExists ) {
-                               if ( !$user->isLoggedIn() ) {
-                                       $this->createGoogleUserForm( $userInfo, 
$db );
-                               } else {
-                                       $this->GoogleUserForm( 'Merge' );
-                               }
-                       } else {
-                               if ( $user->isLoggedIn() ) {
-                                       if ( $user->getId() != 
$googleIdExists['id'] ) {
-                                               $out->addWikiMsg( 
'googlelogin-link-other' );
+                       if (
+                               $this->isValidDomain(
+                                       $this->getHost(
+                                               $userInfo['emails'][0]['value']
+                                       )
+                               )
+                       ) {
+                               if ( !$googleIdExists ) {
+                                       if ( !$user->isLoggedIn() ) {
+                                               $this->createGoogleUserForm( 
$userInfo, $db );
                                        } else {
-                                               if ( $request->getVal( 'code' ) 
!== null ) {
-                                                       // if user logged into 
google account and is already logged in and linked,
-                                                       // show the whole 
special page, not only a button - bug 67486
-                                                       $out->redirect( 
$this->getPageTitle()->getLocalUrl() );
-                                               } else {
-                                                       $this->GoogleUserForm( 
'Unlink' );
-                                               }
+                                               $this->GoogleUserForm( 'Merge' 
);
                                        }
                                } else {
-                                       $this->loginGoogleUser( 
$googleIdExists['id'] );
+                                       if ( $user->isLoggedIn() ) {
+                                               if ( $user->getId() != 
$googleIdExists['id'] ) {
+                                                       $out->addWikiMsg( 
'googlelogin-link-other' );
+                                               } else {
+                                                       if ( $request->getVal( 
'code' ) !== null ) {
+                                                               // if user 
logged into google account and is already logged in and linked,
+                                                               // show the 
whole special page, not only a button - bug 67486
+                                                               $out->redirect( 
$this->getPageTitle()->getLocalUrl() );
+                                                       } else {
+                                                               
$this->GoogleUserForm( 'Unlink' );
+                                                       }
+                                               }
+                                       } else {
+                                               $this->loginGoogleUser( 
$googleIdExists['id'] );
+                                       }
                                }
+                       } else {
+                               $out->addWikiMsg(
+                                       'googlelogin-unallowed-domain',
+                                       $this->getHost(
+                                               $userInfo['emails'][0]['value']
+                                       )
+                               );
                        }
+               }
+
+               /**
+                * Creates the TLD cache from which the valid tld of mail 
domain comes from.
+                * @param string $cacheFile The file to create the cache too 
(must be writeable for the
+                * webserver!)
+                * @param int $max_tl How deep the domain list is (enclude 
example.co.uk (2) or
+                * example.lib.wy.us (3)?)
+                * @see 
http://www.programmierer-forum.de/domainnamen-ermitteln-t244185.htm
+                */
+               function createTLDCache( $cacheFile, $max_tl = 2 ) {
+                       $cacheFolder = str_replace( basename( $cacheFile ), '', 
$cacheFile );
+                       if ( !is_writable( $cacheFolder ) ) {
+                               throw new MWException( $cacheFolder . ' is not 
writeable!' );
+                       }
+                       $tlds = file(
+                               
'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1'
+                       );
+                       if ( $tlds === false ) {
+                               throw new MWException( 'Domainlist can not be 
downloaded!' );
+                       }
+                       $i = 0;
+                       // remove unnecessary lines
+                       foreach ( $tlds as $tld ) {
+                               $tlds[ $i ] = trim( $tld );
+                               /**
+                                       empty
+                                       comments
+                                       top level domains
+                                       is overboard
+                               */
+                               if (
+                                       !$tlds[ $i ] ||
+                                       $tld[0] == '/' ||
+                                       strpos( $tld, '.' ) === false ||
+                                       substr_count( $tld, '.' ) >= $max_tl
+                               ) {
+                                       unset( $tlds[ $i ] );
+                               }
+                               $i++;
+                       }
+                       $tlds = array_values( $tlds );
+                       file_put_contents(
+                               $cacheFile,
+                               "<?php\n" . '$tlds = ' . str_replace(
+                                       array( ' ', "\n" ),
+                                       '',
+                                       var_export( $tlds, true )
+                               ) . ";\n?" . ">"
+                       );
+               }
+
+               /**
+                * Returns the domain and tld (without subdomains) of the 
provided E-Mailadress
+                * @param string $domain The domain part of the email address 
to extract from.
+                * @return string The Tld and domain of $domain without 
subdomains
+                * @see 
http://www.programmierer-forum.de/domainnamen-ermitteln-t244185.htm
+                */
+               function getHost( $domain = '' ) {
+                       global $wgGLAllowedDomainsStrict;
+                       if ( $wgGLAllowedDomainsStrict ) {
+                               $domain = explode( '@', $domain );
+                               // we can trust google to give us only valid 
email address, so give the last element
+                               return array_pop( $domain );
+                       }
+                       // for parse_url()
+                       $domain =
+                               !isset($domain[5]) ||
+                               (
+                                       $domain[3] != ':' &&
+                                       $domain[4] != ':' &&
+                                       $domain[5] != ':'
+                               ) ? 'http://' . $domain : $domain;
+                       // remove "/path/file.html", "/:80", etc.
+                       $domain = parse_url( $domain, PHP_URL_HOST );
+                       // separate domain level
+                       $lvl = explode('.', $domain); // 0 => www, 1 => 
example, 2 => co, 3 => uk
+                       // set levels
+                       krsort( $lvl ); // 3 => uk, 2 => co, 1 => example, 0 => 
www
+                       $lvl = array_values( $lvl ); // 0 => uk, 1 => co, 2 => 
example, 3 => www
+                       $_1st = $lvl[0];
+                       $_2nd = isset( $lvl[1] ) ? $lvl[1] . '.' . $_1st : 
false;
+                       $_3rd = isset( $lvl[2] ) ? $lvl[2] . '.' . $_2nd : 
false;
+                       $_4th = isset( $lvl[3] ) ? $lvl[3] . '.' . $_3rd : 
false;
+
+                       // tld extract
+                       if ( !file_exists(__DIR__ . "/cache/tld.txt") ) {
+                               $this->createTLDCache( __DIR__ . 
"/cache/tld.txt" );
+                       }
+                       require ( __DIR__ . "/cache/tld.txt" );
+                       $tlds = array_flip( $tlds );
+                       if ( // fourth level is TLD
+                               $_4th &&
+                               !isset( $tlds[ '!' . $_4th ] ) &&
+                               (
+                                       isset( $tlds[ $_4th ] ) ||
+                                       isset( $tlds[ '*.' . $_3rd ] )
+                               )
+                       ) {
+                               $domain = isset( $lvl[4] ) ? $lvl[4] . '.' . 
$_4th : false;
+                       } elseif ( // third level is TLD
+                               $_3rd &&
+                               !isset( $tlds[ '!' . $_3rd ] ) &&
+                               (
+                                       isset($tlds[ $_3rd ]) ||
+                                       isset( $tlds[ '*.' . $_2nd ] )
+                               )
+                       ) {
+                               $domain = $_4th;
+                       } elseif ( // second level is TLD
+                               !isset( $tlds[ '!' . $_2nd ] ) &&
+                               (
+                                       isset( $tlds[ $_2nd ] ) ||
+                                       isset( $tlds[ '*.' . $_1st ] )
+                               )
+                       ) {
+                               $domain = $_3rd;
+                       } else { // first level is TLD
+                               $domain = $_2nd;
+                       }
+                       return $domain;
+               }
+               /**
+                * If restriction of domains is enabled, check if the user 
E-Mail is valid before do anything.
+                * @param string $mailDomain The domain of email address
+                * @return boolean
+                */
+               private function isValidDomain( $mailDomain ) {
+                       global $wgGLAllowedDomains;
+                       if ( is_array( $wgGLAllowedDomains ) ) {
+                               if ( in_array( $mailDomain, $wgGLAllowedDomains 
) ) {
+                                       return true;
+                               }
+                               return false;
+                       }
+                       return true;
                }
 
                /**
@@ -180,8 +331,8 @@
                 */
                private function prepareClient( $client ) {
                        global $wgGLSecret, $wgGLAppId, $wgGLAppName;
-                       $client->setClientId( $wgGoogleAppId );
-                       $client->setClientSecret( $wgGoogleSecret );
+                       $client->setClientId( $wgGLAppId );
+                       $client->setClientSecret( $wgGLSecret );
                        $client->setRedirectUri( 
WebRequest::detectServer().$this->getPageTitle()->getLocalUrl() );
                        $client->addScope( 
"https://www.googleapis.com/auth/userinfo.profile"; );
                        $client->addScope( 
"https://www.googleapis.com/auth/userinfo.email"; );
@@ -414,7 +565,7 @@
                                                                
$user->setCookies();
                                                                // create a log 
entry for the created user - bug 67245
                                                                $createReason = 
'';
-                                                               if ( 
$wgGoogleShowCreateReason ) {
+                                                               if ( 
$wgGLShowCreateReason ) {
                                                                        
$createReason =
                                                                                
'via [[' . $this->getPageTitle() . '|Google Login]]';
                                                                }
diff --git a/cache/README b/cache/README
new file mode 100644
index 0000000..a173c87
--- /dev/null
+++ b/cache/README
@@ -0,0 +1 @@
+This folder is for files the Script generates automatically.
\ No newline at end of file
diff --git a/i18n/de.json b/i18n/de.json
index 4374f96..564bbe7 100644
--- a/i18n/de.json
+++ b/i18n/de.json
@@ -10,6 +10,7 @@
        "googlelogin-desc": "Stellt eine [[Special:GoogleLogin|Spezialseite]] 
zur Verfügung, die es Nutzern erlaubt, sich mit Ihrem Google-Konto anzumelden.",
        "googlelogin-parerror": "Die aufgerufene Seite existiert nicht. Bitte 
gehen Sie zurück und versuchen die Aktion erneut.",
        "googlelogin-generic-error": "Oops, da war ein Problem. Bitte gehen Sie 
zurück und versuchen die Aktion erneut. Fehlernachricht: $1",
+       "googlelogin-unallowed-domain": "Die E-Mail-Domain, welche von deiner 
primären E-Mailadresse verwendet wird ($1), ist für die Anmeldung mit 
GoogleLogin in diesem Wiki nicht erlaubt.",
        "googlelogin-form-choosename-title": "Wähle Benutzername",
        "googlelogin-form-choosename": "Wähle einen Benutzernamen um ein Konto 
zu erstellen",
        "googlelogin-form-choosename-finish-title": "Benutzerkonto erstellen",
diff --git a/i18n/en.json b/i18n/en.json
index dc796cd..0816910 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -8,6 +8,7 @@
        "googlelogin-desc": "Provides a [[Special:GoogleLogin|Special page]] to 
allow users to login with their Google accounts",
        "googlelogin-parerror": "The requested page doesn't exist. Please go 
back and try the action again.",
        "googlelogin-generic-error": "Oops, there was an error. Please go back 
and try again. Message: $1",
+       "googlelogin-unallowed-domain": "The email domain used for the primary 
email address of your Google account ($1) isn't allowed to login into this 
wiki.",
        "googlelogin-form-choosename-title": "Choose username",
        "googlelogin-form-choosename": "Please choose your username to create a 
wiki account",
        "googlelogin-form-choosename-finish-title": "Create wiki account",
@@ -30,7 +31,7 @@
        "googlelogin-linkstatus": "Link status",
        "googlelogin-linked": "linked",
        "googlelogin-unlinked": "not linked",
-       "googlelogin-link-other": "Your Google account is already linked to 
another user. Your Google account can linked only to one wiki account. Please 
unlink the connection to your other wiki account or contact an administrator, 
if you haven't another wiki account.",
+       "googlelogin-link-other": "Your Google account is already linked to 
another user. Please unlink the connection or contact an administrator, if you 
have no other wiki account.",
        "googlelogin-success-merge": "Congratulations! Your wiki account is now 
linked to your Google account.",
        "googlelogin-success-unlink": "Congratulations! Your wiki account isn't 
linked to your Google account anymore."
-}
\ No newline at end of file
+}
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 919401b..cfaff6d 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -9,6 +9,7 @@
        "googlelogin-desc": "{{desc|name=Google 
Login|url=http://www.mediawiki.org/wiki/Extension:GoogleLogin}}";,
        "googlelogin-parerror": "Error message when a Subpage of 
Special:GoogleLogin is requested, which does not exist.",
        "googlelogin-generic-error": "Generic error message for errors with no 
specific error message.\n\nParameters:\n* $1 - a short description of the error 
(e.g. Database error)",
+       "googlelogin-unallowed-domain": "The domain of the user isn't allowed 
to use with Google Login, show this as an error message. $1 is the E-Maildomain 
used.",
        "googlelogin-form-choosename-title": "Title of SpecialPage when the 
user can create a new user and has to choose an Username.",
        "googlelogin-form-choosename": "Title of fieldset to explain shortly, 
what the user has to do (choose username).",
        "googlelogin-form-choosename-finish-title": "Title of Subpage 'Finish' 
after the Useraccount is successful created.",

-- 
To view, visit https://gerrit.wikimedia.org/r/142741
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I00b9cb9b844d5fbebe3bcb12f101d91ff609014c
Gerrit-PatchSet: 12
Gerrit-Project: mediawiki/extensions/GoogleLogin
Gerrit-Branch: master
Gerrit-Owner: Florianschmidtwelzow <florian.schmidt.wel...@t-online.de>
Gerrit-Reviewer: Florianschmidtwelzow <florian.schmidt.wel...@t-online.de>
Gerrit-Reviewer: Siebrand <siebr...@kitano.nl>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to