Google Apps Login - Version 2.5

Version Description

Platform extended to provide Service Account settings.

Download this release

Release Info

Developer danlester
Plugin Icon 128x128 Google Apps Login
Version 2.5
Comparing to
See all releases

Code changes from version 2.4.4 to 2.5

core/Google/Auth/AssertionCredentials.php CHANGED
@@ -17,6 +17,7 @@
17
 
18
  require_once "Google/Auth/OAuth2.php";
19
  require_once "Google/Signer/P12.php";
 
20
  require_once "Google/Utils.php";
21
 
22
  /**
@@ -34,6 +35,7 @@ class GoogleGAL_Auth_AssertionCredentials
34
  public $privateKeyPassword;
35
  public $assertionType;
36
  public $sub;
 
37
  /**
38
  * @deprecated
39
  * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
@@ -71,6 +73,10 @@ class GoogleGAL_Auth_AssertionCredentials
71
  $this->useCache = $useCache;
72
  }
73
 
 
 
 
 
74
  /**
75
  * Generate a unique key to represent this credential.
76
  * @return string
@@ -129,7 +135,7 @@ class GoogleGAL_Auth_AssertionCredentials
129
  );
130
 
131
  $signingInput = implode('.', $segments);
132
- $signer = new GoogleGAL_Signer_P12($this->privateKey, $this->privateKeyPassword);
133
  $signature = $signer->sign($signingInput);
134
  $segments[] = GoogleGAL_Utils::urlSafeB64Encode($signature);
135
 
17
 
18
  require_once "Google/Auth/OAuth2.php";
19
  require_once "Google/Signer/P12.php";
20
+ require_once "Google/Signer/PEM.php";
21
  require_once "Google/Utils.php";
22
 
23
  /**
35
  public $privateKeyPassword;
36
  public $assertionType;
37
  public $sub;
38
+ public $signerClass = 'GoogleGAL_Signer_P12';
39
  /**
40
  * @deprecated
41
  * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
73
  $this->useCache = $useCache;
74
  }
75
 
76
+ public function setSignerClass($signerClass) {
77
+ $this->signerClass = $signerClass;
78
+ }
79
+
80
  /**
81
  * Generate a unique key to represent this credential.
82
  * @return string
135
  );
136
 
137
  $signingInput = implode('.', $segments);
138
+ $signer = new $this->signerClass($this->privateKey, $this->privateKeyPassword);
139
  $signature = $signer->sign($signingInput);
140
  $segments[] = GoogleGAL_Utils::urlSafeB64Encode($signature);
141
 
core/Google/Signer/PEM.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once 'Google/Auth/Exception.php';
19
+ require_once 'Google/Signer/Abstract.php';
20
+
21
+ /**
22
+ * Signs data with PEM key (e.g. taken from new JSON files).
23
+ *
24
+ * @author Dan Lester <dan@danlester.com>
25
+ */
26
+ class GoogleGAL_Signer_PEM extends GoogleGAL_Signer_Abstract
27
+ {
28
+ // OpenSSL private key resource
29
+ private $privateKey;
30
+
31
+ // Creates a new signer from a PEM text string
32
+ public function __construct($pem, $password)
33
+ {
34
+ if (!function_exists('openssl_x509_read')) {
35
+ throw new GoogleGAL_Exception(
36
+ 'The Google PHP API library needs the openssl PHP extension'
37
+ );
38
+ }
39
+
40
+ $this->privateKey = $pem;
41
+ if (!$this->privateKey) {
42
+ throw new GoogleGAL_Auth_Exception("Unable to load private key");
43
+ }
44
+ }
45
+
46
+ public function __destruct()
47
+ {
48
+ }
49
+
50
+ public function sign($data)
51
+ {
52
+ if (version_compare(PHP_VERSION, '5.3.0') < 0) {
53
+ throw new GoogleGAL_Auth_Exception(
54
+ "PHP 5.3.0 or higher is required to use service accounts."
55
+ );
56
+ }
57
+ $hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256";
58
+ if (!openssl_sign($data, $signature, $this->privateKey, $hash)) {
59
+ throw new GoogleGAL_Auth_Exception("Unable to sign data");
60
+ }
61
+ return $signature;
62
+ }
63
+ }
core/core_google_apps_login.php CHANGED
@@ -32,27 +32,30 @@ class core_google_apps_login {
32
  return $this->newcookievalue;
33
  }
34
 
 
 
 
 
 
 
 
 
35
  protected function createGoogleClient($options, $includeoauth=false) {
36
  // Another plugin might have already included these files
37
  // Unfortunately we just have to hope they have a similar enough version
38
 
39
- set_include_path(get_include_path() . PATH_SEPARATOR . plugin_dir_path(__FILE__));
40
 
41
  // Google PHP Client obtained from https://github.com/google/google-api-php-client
42
  // Using modified Google Client to avoid name clashes - rename process:
43
  // find . -type f -exec sed -i '' -e 's/Google_/GoogleGAL_/g' {} +
44
 
45
- if (!class_exists('GoogleGAL_Client')) {
46
- require_once( 'Google/Client.php' );
47
- }
48
-
49
- $client = new GoogleGAL_Client();
50
- $client->setApplicationName("Wordpress Site");
51
-
52
  $client->setClientId($options['ga_clientid']);
53
  $client->setClientSecret($options['ga_clientsecret']);
54
  $client->setRedirectUri($this->get_login_url());
55
-
56
  $scopes = array_unique(apply_filters('gal_gather_scopes', $this->get_default_scopes()));
57
  $client->setScopes($scopes);
58
  $client->setApprovalPrompt($options['ga_force_permissions'] ? 'force' : 'auto');
@@ -469,7 +472,7 @@ class core_google_apps_login {
469
  ?>
470
  <table class="form-table">
471
  <tbody><tr>
472
- <th>Profile Photo</label></th>
473
  <td><?php echo get_avatar($wp_user->ID, '48'); ?></td>
474
  <td><?php echo apply_filters('gal_avatar_source_desc', $source_text, $wp_user); ?></td>
475
  </tr>
@@ -534,7 +537,7 @@ class core_google_apps_login {
534
  </h2>
535
 
536
 
537
- <form action="<?php echo $submit_page; ?>" method="post" id="gal_form">
538
 
539
  <?php
540
  settings_fields($this->get_options_pagename());
@@ -605,7 +608,9 @@ class core_google_apps_login {
605
  'google-apps-login'), $this->calculate_instructions_url()."#config" );
606
  echo '</p>';
607
 
608
- $options = $this->get_option_galogin();
 
 
609
  echo '<label for="input_ga_clientid" class="textinput big">'.__('Client ID', 'google-apps-login').'</label>';
610
  echo "<input id='input_ga_clientid' class='textinput' name='".$this->get_options_name()."[ga_clientid]' size='68' type='text' value='".esc_attr($options['ga_clientid'])."' />";
611
  echo '<br class="clear"/><p class="desc big">';
@@ -618,7 +623,108 @@ class core_google_apps_login {
618
  printf( __('Normally something like %s', 'google-apps-login'), 'sHSfR4_jf_2jsy-kjPjgf2dT' );
619
  echo '</p>';
620
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  echo '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
  }
623
 
624
  // Has content in Basic
@@ -688,8 +794,8 @@ class core_google_apps_login {
688
 
689
  public function ga_options_validate($input) {
690
  $newinput = Array();
691
- $newinput['ga_clientid'] = trim($input['ga_clientid']);
692
- $newinput['ga_clientsecret'] = trim($input['ga_clientsecret']);
693
  if(!preg_match('/^.{10}.*$/i', $newinput['ga_clientid'])) {
694
  add_settings_error(
695
  'ga_clientid',
@@ -710,6 +816,47 @@ class core_google_apps_login {
710
  $newinput['ga_force_permissions'] = isset($input['ga_force_permissions']) ? (boolean)$input['ga_force_permissions'] : false;
711
  $newinput['ga_auto_login'] = isset($input['ga_auto_login']) ? (boolean)$input['ga_auto_login'] : false;
712
  $newinput['ga_poweredby'] = isset($input['ga_poweredby']) ? (boolean)$input['ga_poweredby'] : false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713
  $newinput['ga_version'] = $this->PLUGIN_VERSION;
714
  return $newinput;
715
  }
@@ -717,7 +864,18 @@ class core_google_apps_login {
717
  protected function get_error_string($fielderror) {
718
  $local_error_strings = Array(
719
  'ga_clientid|tooshort_texterror' => __('The Client ID should be longer than that', 'google-apps-login') ,
720
- 'ga_clientsecret|tooshort_texterror' => __('The Client Secret should be longer than that', 'google-apps-login')
 
 
 
 
 
 
 
 
 
 
 
721
  );
722
  if (isset($local_error_strings[$fielderror])) {
723
  return $local_error_strings[$fielderror];
@@ -736,7 +894,11 @@ class core_google_apps_login {
736
  'ga_ms_usesubsitecallback' => false,
737
  'ga_force_permissions' => false,
738
  'ga_auto_login' => false,
739
- 'ga_poweredby' => false);
 
 
 
 
740
  }
741
 
742
  protected $ga_options = null;
@@ -744,9 +906,9 @@ class core_google_apps_login {
744
  if ($this->ga_options != null) {
745
  return $this->ga_options;
746
  }
747
-
748
  $option = get_site_option($this->get_options_name(), Array());
749
-
750
  $default_options = $this->get_default_options();
751
  foreach ($default_options as $k => $v) {
752
  if (!isset($option[$k])) {
@@ -758,6 +920,55 @@ class core_google_apps_login {
758
  return $this->ga_options;
759
  }
760
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
761
  public function ga_save_network_options() {
762
  check_admin_referer( $this->get_options_pagename().'-options' );
763
 
@@ -774,7 +985,7 @@ class core_google_apps_login {
774
  }
775
  }
776
 
777
- update_site_option($this->get_options_name(), $outoptions);
778
 
779
  // redirect to settings page in network
780
  wp_redirect(
@@ -815,6 +1026,43 @@ class core_google_apps_login {
815
  return $options['ga_clientid'];
816
  }
817
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
818
  // PLUGINS PAGE
819
 
820
  public function ga_plugin_action_links( $links, $file ) {
@@ -856,4 +1104,7 @@ class core_google_apps_login {
856
 
857
  }
858
 
 
 
 
859
  ?>
32
  return $this->newcookievalue;
33
  }
34
 
35
+ private $doneIncludePath = false;
36
+ private function setIncludePath() {
37
+ if (!$this->doneIncludePath) {
38
+ set_include_path(get_include_path() . PATH_SEPARATOR . plugin_dir_path(__FILE__));
39
+ $this->doneIncludePath = true;
40
+ }
41
+ }
42
+
43
  protected function createGoogleClient($options, $includeoauth=false) {
44
  // Another plugin might have already included these files
45
  // Unfortunately we just have to hope they have a similar enough version
46
 
47
+ $this->setIncludePath();
48
 
49
  // Google PHP Client obtained from https://github.com/google/google-api-php-client
50
  // Using modified Google Client to avoid name clashes - rename process:
51
  // find . -type f -exec sed -i '' -e 's/Google_/GoogleGAL_/g' {} +
52
 
53
+ $client = $this->get_Google_Client();
54
+
 
 
 
 
 
55
  $client->setClientId($options['ga_clientid']);
56
  $client->setClientSecret($options['ga_clientsecret']);
57
  $client->setRedirectUri($this->get_login_url());
58
+
59
  $scopes = array_unique(apply_filters('gal_gather_scopes', $this->get_default_scopes()));
60
  $client->setScopes($scopes);
61
  $client->setApprovalPrompt($options['ga_force_permissions'] ? 'force' : 'auto');
472
  ?>
473
  <table class="form-table">
474
  <tbody><tr>
475
+ <th>Profile Photo</th>
476
  <td><?php echo get_avatar($wp_user->ID, '48'); ?></td>
477
  <td><?php echo apply_filters('gal_avatar_source_desc', $source_text, $wp_user); ?></td>
478
  </tr>
537
  </h2>
538
 
539
 
540
+ <form action="<?php echo $submit_page; ?>" method="post" id="gal_form" enctype="multipart/form-data" >
541
 
542
  <?php
543
  settings_fields($this->get_options_pagename());
608
  'google-apps-login'), $this->calculate_instructions_url()."#config" );
609
  echo '</p>';
610
 
611
+ $options = $this->get_option_galogin(); // Must be in this order to invoke upgrade code
612
+ $saoptions = $this->get_sa_option();
613
+
614
  echo '<label for="input_ga_clientid" class="textinput big">'.__('Client ID', 'google-apps-login').'</label>';
615
  echo "<input id='input_ga_clientid' class='textinput' name='".$this->get_options_name()."[ga_clientid]' size='68' type='text' value='".esc_attr($options['ga_clientid'])."' />";
616
  echo '<br class="clear"/><p class="desc big">';
623
  printf( __('Normally something like %s', 'google-apps-login'), 'sHSfR4_jf_2jsy-kjPjgf2dT' );
624
  echo '</p>';
625
 
626
+ $serviceacct_plugins = apply_filters('gal_gather_serviceacct_reqs', array());
627
+
628
+ echo '<h3>Service Account settings</h3>';
629
+
630
+ if (count($serviceacct_plugins) == 0) {
631
+ ?>
632
+ <p>Some Google Apps extensions may require you to set up a Service Account. If you Activate those extension plugins then
633
+ come back to this page, you will see further instructions, including the 'permission scopes' those extensions require.
634
+ However, if you know you need to set up a Service Account in advance, you can click below to reveal the settings.</p>
635
+
636
+ <p><a href="#" id="gal-show-admin-serviceacct">Show Service Account settings</a></p>
637
+
638
+ <span id="gal-hide-admin-serviceacct" style="display: none;">
639
+
640
+ <?php } ?>
641
+
642
+ <p>In order for all users to have permissions to access domain-level information from Google, you will need to create
643
+ a Service Account. Please see our
644
+ <a href="https://wp-glogin.com/installing-google-apps-login/service-account-setup/?utm_source=ServiceAccount&utm_medium=freemium&utm_campaign=Login" target="_blank">extended instructions here</a>.</p>
645
+
646
+ <?php
647
+ if (count($serviceacct_plugins) > 0) {
648
+ $this->ga_show_service_account_reqs($serviceacct_plugins);
649
+ }
650
+
651
+ echo '<br class="clear">';
652
+ if ($saoptions['ga_serviceemail'] != '') {
653
+ // Display service email
654
+ echo '<label for="input_ga_serviceemail" class="textinput">'.__('Service Account email address', 'google-apps-login').'</label>';
655
+ echo "<div class='gal-lowerinput'>";
656
+ echo "<span id='input_ga_serviceemail'>".htmlentities($saoptions['ga_serviceemail'])."</span>";
657
+ echo '</div>';
658
+ echo '<br class="clear">';
659
+ if ($saoptions['ga_pkey_print'] != '') {
660
+ // Display finger print of key
661
+ echo '<label for="input_ga_pkey_print" class="textinput">'.__('Private key fingerprint', 'google-apps-login').'</label>';
662
+ echo "<div class='gal-lowerinput'>";
663
+ echo "<span id='input_ga_pkey_print'>".htmlentities($saoptions['ga_pkey_print'])."</span>";
664
+ echo '</div>';
665
+ echo '<br class="clear">';
666
+ }
667
+ }
668
+
669
+ echo '<label for="input_ga_keyfile" class="textinput">'.__('Upload Service Account JSON file', 'google-apps-login').'</label>';
670
+ echo "<div class='gal-lowerinput'>";
671
+ echo "<input type='hidden' name='MAX_FILE_SIZE' value='10240' />";
672
+ echo "<input type='file' name='ga_keyfileupload' id='input_ga_keyfileupload' />";
673
  echo '</div>';
674
+ echo '<br class="clear">';
675
+
676
+ echo '<label for="input_ga_domainadmin" class="textinput">'.__('A Google Apps Domain admin\'s email', 'google-apps-login').'</label>';
677
+ echo "<input id='input_ga_domainadmin' name='".$this->get_options_name()."[ga_domainadmin]' size='40' type='text' value='".esc_attr($options['ga_domainadmin'])."' class='textinput' />";
678
+ echo '<br class="clear">';
679
+
680
+ if (count($serviceacct_plugins) == 0) {
681
+ echo '</span>';
682
+ }
683
+
684
+ echo '</div>';
685
+ }
686
+
687
+ protected function ga_show_service_account_reqs($serviceacct_plugins) {
688
+ $all_scopes = array();
689
+ ?>
690
+ <p>A Service Account will be required for the following extensions, and they need the permission scopes listed:
691
+ <table class="gal-admin-service-scopes">
692
+ <thead>
693
+ <tr>
694
+ <td>Extension Name</td>
695
+ <td>Scopes Requested</td>
696
+ <td>Reason</td>
697
+ </tr>
698
+ </thead>
699
+ <tbody>
700
+ <?php
701
+ foreach ($serviceacct_plugins as $plg) {
702
+ if (is_array($plg) && count($plg) == 2) {
703
+ $i = 0;
704
+ foreach ($plg[1] as $k => $v) {
705
+ echo '<tr>';
706
+ if ($i==0) {
707
+ echo '<td rowspan="'.count($plg[1]).'">'.htmlentities($plg[0]).'</td>';
708
+ }
709
+ echo '<td>'.htmlentities($k).'</td>';
710
+ echo '<td>'.htmlentities($v).'</td>';
711
+ echo '</tr>';
712
+ $all_scopes[] = $k;
713
+ ++$i;
714
+ }
715
+ }
716
+ }
717
+ ?>
718
+ </tbody>
719
+ </table>
720
+ </p>
721
+
722
+ <p>Here is a comma-separated list of scopes to copy and paste into your Google Apps admin security page (see instructions).
723
+ <br />
724
+ <div class="gal-admin-scopes-list"><?php echo htmlentities(implode(', ',array_unique($all_scopes))); ?></div>
725
+ </p>
726
+ <?php
727
+
728
  }
729
 
730
  // Has content in Basic
794
 
795
  public function ga_options_validate($input) {
796
  $newinput = Array();
797
+ $newinput['ga_clientid'] = isset($input['ga_clientid']) ? trim($input['ga_clientid']) : '';
798
+ $newinput['ga_clientsecret'] = isset($input['ga_clientsecret']) ? trim($input['ga_clientsecret']) : '';
799
  if(!preg_match('/^.{10}.*$/i', $newinput['ga_clientid'])) {
800
  add_settings_error(
801
  'ga_clientid',
816
  $newinput['ga_force_permissions'] = isset($input['ga_force_permissions']) ? (boolean)$input['ga_force_permissions'] : false;
817
  $newinput['ga_auto_login'] = isset($input['ga_auto_login']) ? (boolean)$input['ga_auto_login'] : false;
818
  $newinput['ga_poweredby'] = isset($input['ga_poweredby']) ? (boolean)$input['ga_poweredby'] : false;
819
+
820
+ // Service account settings
821
+ $newinput['ga_domainadmin'] = isset($input['ga_domainadmin']) ? trim($input['ga_domainadmin']) : '';
822
+ if (!preg_match('/^([A-Za-z0-9._%+-]+@([0-9a-z-]+\.)?[0-9a-z-]+\.[a-z]{2,7})?$/', $newinput['ga_domainadmin'])) {
823
+ add_settings_error(
824
+ 'ga_domainadmin',
825
+ 'invalid_email',
826
+ self::get_error_string('ga_domainadmin|invalid_email'),
827
+ 'error'
828
+ );
829
+ }
830
+
831
+ // Submitting a JSON key for Service Account
832
+ if (isset($_FILES['ga_keyfileupload'])) {
833
+ if (!class_exists('gal_keyfile_uploader')) {
834
+ $this->setIncludePath();
835
+ require_once( 'keyfile_uploader.php' );
836
+ }
837
+
838
+ $saoptions = $this->get_sa_option();
839
+
840
+ $kfu = new gal_keyfile_uploader('ga_keyfileupload');
841
+ $newemail = $kfu->getEmail();
842
+ $newkey = $kfu->getKey();
843
+ $newprint = $kfu->getPrint();
844
+ if ($newemail != '' && $newkey != '') {
845
+ $saoptions['ga_serviceemail'] = $newemail;
846
+ $saoptions['ga_sakey'] = $newkey;
847
+ $saoptions['ga_pkey_print'] = $newprint;
848
+ $this->save_sa_option($saoptions);
849
+ }
850
+ else if (($kfuerror = $kfu->getError()) != '') {
851
+ add_settings_error(
852
+ 'ga_jsonkeyfile',
853
+ $kfuerror,
854
+ self::get_error_string('ga_jsonkeyfile|'.$kfuerror),
855
+ 'error'
856
+ );
857
+ }
858
+ }
859
+
860
  $newinput['ga_version'] = $this->PLUGIN_VERSION;
861
  return $newinput;
862
  }
864
  protected function get_error_string($fielderror) {
865
  $local_error_strings = Array(
866
  'ga_clientid|tooshort_texterror' => __('The Client ID should be longer than that', 'google-apps-login') ,
867
+ 'ga_clientsecret|tooshort_texterror' => __('The Client Secret should be longer than that', 'google-apps-login'),
868
+ 'ga_serviceemail|invalid_email' => __('Service Account email must be a valid email addresses', 'google-apps-login'),
869
+ 'ga_domainadmin|invalid_email' => __('Google Apps domain admin must be a valid email address of one of your Google Apps admins', 'google-apps-login'),
870
+ 'ga_jsonkeyfile|file_upload_error' => __('Error with file upload on the server', 'google-apps-login'),
871
+ 'ga_jsonkeyfile|file_upload_error2' => __('Error with file upload on the server - file was too large', 'google-apps-login'),
872
+ 'ga_jsonkeyfile|file_upload_error6' => __('Error with file upload on the server - no temp directory exists', 'google-apps-login'),
873
+ 'ga_jsonkeyfile|file_upload_error7' => __('Error with file upload on the server - failed to write to disk', 'google-apps-login'),
874
+ 'ga_jsonkeyfile|no_content' => __('JSON key file was empty'),
875
+ 'ga_jsonkeyfile|decode_error' => __('JSON key file could not be decoded correctly'),
876
+ 'ga_jsonkeyfile|missing_values' => __('JSON key file does not contain all of client_email, private_key, and type'),
877
+ 'ga_jsonkeyfile|not_serviceacct' => __('JSON key file does not represent a Service Account'),
878
+ 'ga_jsonkeyfile|bad_pem' => __('Key cannot be coerced into a PEM key - invalid format in private_key of JSON key file')
879
  );
880
  if (isset($local_error_strings[$fielderror])) {
881
  return $local_error_strings[$fielderror];
894
  'ga_ms_usesubsitecallback' => false,
895
  'ga_force_permissions' => false,
896
  'ga_auto_login' => false,
897
+ 'ga_poweredby' => false,
898
+ //'ga_serviceemail' => '',
899
+ //'ga_keyfilepath' => '',
900
+ 'ga_sakey' => '',
901
+ 'ga_domainadmin' => '');
902
  }
903
 
904
  protected $ga_options = null;
906
  if ($this->ga_options != null) {
907
  return $this->ga_options;
908
  }
909
+
910
  $option = get_site_option($this->get_options_name(), Array());
911
+
912
  $default_options = $this->get_default_options();
913
  foreach ($default_options as $k => $v) {
914
  if (!isset($option[$k])) {
920
  return $this->ga_options;
921
  }
922
 
923
+ protected function save_option_galogin($option) {
924
+ update_site_option($this->get_options_name(), $option);
925
+ $this->ga_options = $option;
926
+ }
927
+
928
+ // Options for service account only
929
+ protected function get_sa_options_name() {
930
+ return 'ga_serviceacct';
931
+ }
932
+
933
+ protected $ga_sa_options = null;
934
+ protected function get_sa_option() {
935
+ if ($this->ga_sa_options != null) {
936
+ return $this->ga_sa_options;
937
+ }
938
+
939
+ $ga_sa_options = get_site_option($this->get_sa_options_name(), Array());
940
+
941
+ // Do we need to convert to separate service account settings, from older version?
942
+ if (count($ga_sa_options) == 0) {
943
+ $option = $this->get_option_galogin();
944
+ if (isset($option['ga_keyfilepath']) || isset($option['ga_serviceemail'])) {
945
+ $this->setIncludePath();
946
+ if (!function_exists('gal_service_account_upgrade')) {
947
+ require_once( 'service_account_upgrade.php' );
948
+ gal_service_account_upgrade($option, $this->get_options_name(), $ga_sa_options, $this->get_sa_options_name());
949
+ // options were updated by reference
950
+ $this->save_option_galogin($option);
951
+ $this->save_sa_option($ga_sa_options);
952
+ }
953
+ }
954
+ }
955
+
956
+ // Set defaults
957
+ foreach (array('ga_sakey', 'ga_serviceemail', 'ga_pkey_print') as $k) {
958
+ if (!isset($ga_sa_options[$k])) {
959
+ $ga_sa_options[$k] = '';
960
+ }
961
+ }
962
+
963
+ $this->ga_sa_options = $ga_sa_options;
964
+ return $this->ga_sa_options;
965
+ }
966
+
967
+ protected function save_sa_option($saoptions) {
968
+ update_site_option($this->get_sa_options_name(), $saoptions);
969
+ $this->ga_sa_options = $saoptions;
970
+ }
971
+
972
  public function ga_save_network_options() {
973
  check_admin_referer( $this->get_options_pagename().'-options' );
974
 
985
  }
986
  }
987
 
988
+ $this->save_option_galogin($outoptions);
989
 
990
  // redirect to settings page in network
991
  wp_redirect(
1026
  return $options['ga_clientid'];
1027
  }
1028
 
1029
+ public function get_Auth_AssertionCredentials($scopes) {
1030
+ $options = $this->get_option_galogin();
1031
+ $saoptions = $this->get_sa_option();
1032
+ $this->setIncludePath();
1033
+ if (!class_exists('GoogleGAL_Auth_AssertionCredentials')) {
1034
+ require_once( 'Google/Auth/AssertionCredentials.php' );
1035
+ }
1036
+
1037
+ if ($saoptions['ga_serviceemail'] == '' || $options['ga_domainadmin'] == '' || $saoptions['ga_sakey'] == '') {
1038
+ throw new GAL_Service_Exception('Please configure Service Account in Google Apps Login setup');
1039
+ }
1040
+
1041
+ $cred = new GoogleGAL_Auth_AssertionCredentials(
1042
+ // Replace this with the email address from the client.
1043
+ $saoptions['ga_serviceemail'],
1044
+ // Replace this with the scopes you are requesting.
1045
+ $scopes,
1046
+ $saoptions['ga_sakey'],
1047
+ ''
1048
+ );
1049
+ $cred->setSignerClass('GoogleGAL_Signer_PEM');
1050
+
1051
+ $cred->sub = $options['ga_domainadmin'];
1052
+ return $cred;
1053
+ }
1054
+
1055
+ public function get_Google_Client() {
1056
+ $this->setIncludePath();
1057
+ if (!class_exists('GoogleGAL_Client')) {
1058
+ require_once( 'Google/Client.php' );
1059
+ }
1060
+
1061
+ $client = new GoogleGAL_Client();
1062
+ $client->setApplicationName("Wordpress Site");
1063
+ return $client;
1064
+ }
1065
+
1066
  // PLUGINS PAGE
1067
 
1068
  public function ga_plugin_action_links( $links, $file ) {
1104
 
1105
  }
1106
 
1107
+ class GAL_Service_Exception extends Exception {
1108
+ }
1109
+
1110
  ?>
core/keyfile_uploader.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class gal_keyfile_uploader {
4
+
5
+ protected $fileindex = '';
6
+ public function __construct($fileindex) {
7
+ $this->fileindex = $fileindex;
8
+ $this->attempt_upload();
9
+ }
10
+
11
+ protected function attempt_upload() {
12
+ // If there was an attempt to upload a file
13
+ if (isset($_FILES[$this->fileindex])
14
+ && (!isset($_FILES[$this->fileindex]['error']) || $_FILES[$this->fileindex]['error'] != 4)) {
15
+ // error 4 = no file chosen anyway
16
+
17
+ if (isset($_FILES[$this->fileindex]['error']) && $_FILES[$this->fileindex]['error'] != 0) {
18
+ error_log('JSON Key file upload error number '.$_FILES[$this->fileindex]['error']);
19
+ // Some import errors have error explanations
20
+ $this->error = 'file_upload_error'.(in_array($_FILES[$this->fileindex]['error'], array(2,6,7)) ? $_FILES[$this->fileindex]['error'] : '');
21
+ return;
22
+ }
23
+
24
+ if (isset($_FILES[$this->fileindex]['size']) && $_FILES[$this->fileindex]['size'] <= 0) {
25
+ ob_start();
26
+ var_dump($_FILES[$this->fileindex]);
27
+ error_log(ob_get_clean());
28
+
29
+ $this->error = 'no_content';
30
+ return;
31
+ }
32
+
33
+ $this->read_json($_FILES[$this->fileindex]['tmp_name']);
34
+ }
35
+ }
36
+
37
+ protected function read_json($filepath) {
38
+ $contents = @file_get_contents($filepath);
39
+ $fullkey = json_decode($contents, TRUE);
40
+ if ($fullkey === null || !is_array($fullkey)) {
41
+ $this->error = 'decode_error';
42
+ return;
43
+ }
44
+ if (!isset($fullkey['client_email']) || !isset($fullkey['private_key']) || !isset($fullkey['type'])
45
+ || $fullkey['client_email'] == '' || $fullkey['private_key'] == '') {
46
+ $this->error = 'missing_values';
47
+ return;
48
+ }
49
+ if (isset($fullkey['type']) && $fullkey['type'] != 'service_account') {
50
+ $this->error = 'not_serviceacct';
51
+ return;
52
+ }
53
+
54
+ if (!$this->test_key($fullkey['private_key'])) {
55
+ $this->error = 'bad_pem';
56
+ return;
57
+ }
58
+
59
+ $this->key = $fullkey['private_key'];
60
+ $this->email = $fullkey['client_email'];
61
+ $this->pkeyprint = isset($fullkey['private_key_id']) ? $fullkey['private_key_id'] : '<unspecified>';
62
+ }
63
+
64
+ protected function test_key($pemkey) {
65
+ $hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256";
66
+ $data = 'test data';
67
+ $signature = '';
68
+ if (!@openssl_sign($data, $signature, $pemkey, $hash)) {
69
+ return false;
70
+ }
71
+ return $signature != '' ? true : false;
72
+ }
73
+
74
+ protected $email = '';
75
+ public function getEmail() {
76
+ return $this->email;
77
+ }
78
+
79
+ protected $key = '';
80
+ public function getKey() {
81
+ return $this->key;
82
+ }
83
+
84
+ protected $pkeyprint = '';
85
+ public function getPrint() {
86
+ return $this->pkeyprint;
87
+ }
88
+
89
+ protected $error = '';
90
+ public function getError() {
91
+ return $this->error;
92
+ }
93
+ }
core/service_account_upgrade.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function gal_service_account_upgrade(&$option, $gal_option_name, &$existing_sa_options, $gal_sa_option_name) {
4
+ /* Convert ga_serviceemail ga_keyfilepath
5
+ * into new separate sa options:
6
+ * ga_sakey, ga_serviceemail, ga_pkey_print
7
+ */
8
+
9
+ if (count($existing_sa_options)) {
10
+ return;
11
+ }
12
+
13
+ $existing_sa_options = array('ga_serviceemail' => isset($option['ga_serviceemail']) ? $option['ga_serviceemail'] : '',
14
+ 'ga_sakey' => '',
15
+ 'ga_pkey_print' => '<unspecified>');
16
+
17
+ try {
18
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0 && function_exists('openssl_x509_read')) {
19
+ if (isset($option['ga_keyfilepath']) && $option['ga_keyfilepath'] != '' && file_exists($option['ga_keyfilepath'])) {
20
+ $p12key = @file_get_contents($option['ga_keyfilepath']);
21
+
22
+ $certs = array();
23
+ if (openssl_pkcs12_read($p12key, $certs, 'notasecret')) {
24
+ if (array_key_exists("pkey", $certs) && $certs["pkey"]) {
25
+ $privateKey = openssl_pkey_get_private($certs['pkey']);
26
+ $pemString = '';
27
+ if (openssl_pkey_export($privateKey, $pemString)) {
28
+ $existing_sa_options['ga_sakey'] = $pemString;
29
+ }
30
+ openssl_pkey_free($privateKey);
31
+
32
+ @unlink($options['ga_keyfilepath']);
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ catch (Exception $e) {
39
+ // Never mind
40
+ }
41
+
42
+ // Remove redundant parts of regular options
43
+ unset($option['ga_serviceemail']);
44
+ unset($option['ga_keyfilepath']);
45
+ }
css/gal-admin.css CHANGED
@@ -107,4 +107,35 @@ div#logs-section table tr.gal_log_level4 {
107
 
108
  div#logs-section table tr.gal_log_level3 {
109
  color: red;
110
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  div#logs-section table tr.gal_log_level3 {
109
  color: red;
110
+ }
111
+
112
+ .gal-lowerinput {
113
+ margin-top: 12px;
114
+ }
115
+
116
+ .gal-admin-scopes-list {
117
+ background-color: lightyellow;
118
+ border: 1px solid gray;
119
+ border-radius: 3px;
120
+ max-width: 600px;
121
+ overflow: hidden;
122
+ overflow-x: scroll;
123
+ padding: 0 2px;
124
+ cursor: text;
125
+ white-space: nowrap;
126
+ }
127
+
128
+ table.gal-admin-service-scopes {
129
+ border: 1px solid;
130
+ }
131
+
132
+ table.gal-admin-service-scopes td {
133
+ padding: 4px;
134
+ vertical-align: top;
135
+ }
136
+
137
+ table.gal-admin-service-scopes thead {
138
+ background-color: white;
139
+ font-style: italic;
140
+ }
141
+
google_apps_login.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin Name: Google Apps Login
5
  * Plugin URI: http://wp-glogin.com/
6
  * Description: Simple secure login for Wordpress through users' Google Apps accounts (uses secure OAuth2, and MFA if enabled)
7
- * Version: 2.4.4
8
  * Author: Dan Lester
9
  * Author URI: http://wp-glogin.com/
10
  * License: GPL3
@@ -17,7 +17,7 @@ require_once( plugin_dir_path(__FILE__).'/core/core_google_apps_login.php' );
17
 
18
  class basic_google_apps_login extends core_google_apps_login {
19
 
20
- protected $PLUGIN_VERSION = '2.4.4';
21
 
22
  // Singleton
23
  private static $instance = null;
@@ -38,7 +38,7 @@ class basic_google_apps_login extends core_google_apps_login {
38
  if (!$old_options) {
39
  $new_options = $this->get_option_galogin();
40
  $new_option['ga_poweredby'] = true;
41
- update_site_option($this->get_options_name(), $new_option);
42
  }
43
  }
44
 
@@ -54,6 +54,7 @@ class basic_google_apps_login extends core_google_apps_login {
54
  $drivelink = "http://wp-glogin.com/drive/?utm_source=Admin%20Sidebar&utm_medium=freemium&utm_campaign=Drive";
55
  $upgradelink = "http://wp-glogin.com/google-apps-login-premium/?utm_source=Admin%20Sidebar&utm_medium=freemium&utm_campaign=Freemium";
56
  $avatarslink = "http://wp-glogin.com/avatars/?utm_source=Admin%20Sidebar&utm_medium=freemium&utm_campaign=Avatars";
 
57
 
58
  $adverts = Array();
59
 
@@ -77,13 +78,20 @@ class basic_google_apps_login extends core_google_apps_login {
77
  .'</a>'
78
  .'<span>Bring your site to life with <a href="'.$avatarslink.'" target="_blank">Google Profile Avatars</a></span>'
79
  .'</div>';
 
 
 
 
 
 
 
80
 
81
  $startnum = (int)date('j');
82
 
83
  echo '<div id="gal-tableright" class="gal-tablecell">';
84
 
85
  for ($i=0 ; $i<2 ; $i++) {
86
- echo $adverts[($startnum+$i) % 3];
87
  }
88
 
89
  echo '</div>';
4
  * Plugin Name: Google Apps Login
5
  * Plugin URI: http://wp-glogin.com/
6
  * Description: Simple secure login for Wordpress through users' Google Apps accounts (uses secure OAuth2, and MFA if enabled)
7
+ * Version: 2.5
8
  * Author: Dan Lester
9
  * Author URI: http://wp-glogin.com/
10
  * License: GPL3
17
 
18
  class basic_google_apps_login extends core_google_apps_login {
19
 
20
+ protected $PLUGIN_VERSION = '2.5';
21
 
22
  // Singleton
23
  private static $instance = null;
38
  if (!$old_options) {
39
  $new_options = $this->get_option_galogin();
40
  $new_option['ga_poweredby'] = true;
41
+ $this->save_option_galogin($new_option);
42
  }
43
  }
44
 
54
  $drivelink = "http://wp-glogin.com/drive/?utm_source=Admin%20Sidebar&utm_medium=freemium&utm_campaign=Drive";
55
  $upgradelink = "http://wp-glogin.com/google-apps-login-premium/?utm_source=Admin%20Sidebar&utm_medium=freemium&utm_campaign=Freemium";
56
  $avatarslink = "http://wp-glogin.com/avatars/?utm_source=Admin%20Sidebar&utm_medium=freemium&utm_campaign=Avatars";
57
+ $aioilink = "http://wp-glogin.com/all-in-one-intranet/?utm_source=Admin%20Sidebar&utm_medium=freemium&utm_campaign=AIOI";
58
 
59
  $adverts = Array();
60
 
78
  .'</a>'
79
  .'<span>Bring your site to life with <a href="'.$avatarslink.'" target="_blank">Google Profile Avatars</a></span>'
80
  .'</div>';
81
+
82
+ $adverts[] = '<div>'
83
+ .'<a href="'.$aioilink.'" target="_blank">'
84
+ .'<img src="'.$this->my_plugin_url().'img/basic_aioi.png" />'
85
+ .'</a>'
86
+ .'<span>Instantly turn WordPress into a corporate intranet with <a href="'.$aioilink.'" target="_blank">All-In-One Intranet</a></span>'
87
+ .'</div>';
88
 
89
  $startnum = (int)date('j');
90
 
91
  echo '<div id="gal-tableright" class="gal-tablecell">';
92
 
93
  for ($i=0 ; $i<2 ; $i++) {
94
+ echo $adverts[($startnum+$i) % 4];
95
  }
96
 
97
  echo '</div>';
img/basic_aioi.png ADDED
Binary file
js/gal-admin.js CHANGED
@@ -45,4 +45,31 @@ jQuery(document).ready(function() {
45
  };
46
  jQuery('#input_ga_disablewplogin').on('click', clickfn2);
47
  clickfn2();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  });
45
  };
46
  jQuery('#input_ga_disablewplogin').on('click', clickfn2);
47
  clickfn2();
48
+
49
+ // Show service account button
50
+ jQuery('#gal-show-admin-serviceacct').on('click', function(e) {
51
+ jQuery('#gal-hide-admin-serviceacct').show();
52
+ jQuery('#gal-show-admin-serviceacct').hide();
53
+ e.preventDefault();
54
+ });
55
+
56
+ // Copy and paste click
57
+ function selectText(element) {
58
+ var range, selection;
59
+
60
+ if (document.body.createTextRange) { //ms
61
+ range = document.body.createTextRange();
62
+ range.moveToElementText(element);
63
+ range.select();
64
+ } else if (window.getSelection) { //all others
65
+ selection = window.getSelection();
66
+ range = document.createRange();
67
+ range.selectNodeContents(element);
68
+ selection.removeAllRanges();
69
+ selection.addRange(range);
70
+ }
71
+ }
72
+ jQuery('.gal-admin-scopes-list').on('click', function(e) {
73
+ selectText(e.target);
74
+ });
75
  });
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Plugin Name ===
2
  Contributors: danlester
3
  Tags: login, google, authentication, oauth2, oauth, admin, google apps, sso, single-sign-on, auth, intranet
4
- Requires at least: 3.3
5
  Tested up to: 3.9
6
- Stable tag: 2.4.4
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
@@ -22,7 +22,7 @@ Plugin setup requires you to have admin access to any Google Apps domain, or a r
22
 
23
  Full support and premium features are also available for purchase:
24
 
25
- Eliminate the need for Google Apps domain admins to separately manage WordPress user accounts, and get piece
26
  of mind that only authorized employees have access to the organizations's websites and intranet.
27
 
28
  See [http://wp-glogin.com/google-apps-login-premium/](http://wp-glogin.com/google-apps-login-premium/?utm_source=Login%20Readme%20Top&utm_medium=freemium&utm_campaign=Freemium)
@@ -37,9 +37,12 @@ permissions that users already allowed for Google Apps Login itself.
37
  Using our platform, your website appears to Google accounts as one unified 'web application', making it more secure
38
  and easier to manage.
39
 
40
- [Google Drive Embedder](http://wp-glogin.com/wpgoogledriveembedder) is our free extension plugin allowing
41
  users to browse for Google Drive documents to embed directly in their posts or pages.
42
 
 
 
 
43
  [Google Profile Avatars](http://wp-glogin.com/avatars/?utm_source=Login%20Readme%20Avatars&utm_medium=freemium&utm_campaign=Freemium)
44
  is available on our website. It displays users' Google profile photos in place of their avatars throughout your site.
45
 
@@ -76,6 +79,9 @@ Please see our website [http://wp-glogin.com/](http://wp-glogin.com/?utm_source=
76
  and extra features available in our Premium upgrade, plus support details, other plugins, and useful guides for admins of
77
  WordPress sites and Google Apps.
78
 
 
 
 
79
  == Screenshots ==
80
 
81
  1. User login screen can work as normal or via Google's authentication system
@@ -214,6 +220,10 @@ please [click here](http://wp-glogin.com/installing-google-apps-login/basic-setu
214
 
215
  == Changelog ==
216
 
 
 
 
 
217
  = 2.4.4 =
218
 
219
  Readme updates and tidied settings page.
1
  === Plugin Name ===
2
  Contributors: danlester
3
  Tags: login, google, authentication, oauth2, oauth, admin, google apps, sso, single-sign-on, auth, intranet
4
+ Requires at least: 3.5
5
  Tested up to: 3.9
6
+ Stable tag: 2.5
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
 
22
 
23
  Full support and premium features are also available for purchase:
24
 
25
+ Eliminate the need for Google Apps domain admins to separately manage WordPress user accounts, and get peace
26
  of mind that only authorized employees have access to the organizations's websites and intranet.
27
 
28
  See [http://wp-glogin.com/google-apps-login-premium/](http://wp-glogin.com/google-apps-login-premium/?utm_source=Login%20Readme%20Top&utm_medium=freemium&utm_campaign=Freemium)
37
  Using our platform, your website appears to Google accounts as one unified 'web application', making it more secure
38
  and easier to manage.
39
 
40
+ [Google Drive Embedder](http://wp-glogin.com/wpgoogledriveembedder) is a free extension plugin allowing
41
  users to browse for Google Drive documents to embed directly in their posts or pages.
42
 
43
+ [Google Apps Directory](http://wp-glogin.com/wpgoogleappsdirectory) is a free extension plugin allowing
44
+ logged-in users to search your Google Apps employee directory from a widget on your intranet or client site.
45
+
46
  [Google Profile Avatars](http://wp-glogin.com/avatars/?utm_source=Login%20Readme%20Avatars&utm_medium=freemium&utm_campaign=Freemium)
47
  is available on our website. It displays users' Google profile photos in place of their avatars throughout your site.
48
 
79
  and extra features available in our Premium upgrade, plus support details, other plugins, and useful guides for admins of
80
  WordPress sites and Google Apps.
81
 
82
+ If you are building your organization's intranet on WordPress, try out our
83
+ [All-In-One Intranet plugin](http://wp-glogin.com/all-in-one-intranet/?utm_source=Login%20Readme%20AIOI&utm_medium=freemium&utm_campaign=Freemium).
84
+
85
  == Screenshots ==
86
 
87
  1. User login screen can work as normal or via Google's authentication system
220
 
221
  == Changelog ==
222
 
223
+ = 2.5 =
224
+
225
+ Platform extended to provide Service Account settings.
226
+
227
  = 2.4.4 =
228
 
229
  Readme updates and tidied settings page.