Skip to content

Commit d938276

Browse files
Define theme setting for Google Maps API key
** Why are these changes being introduced: * We received a bug report for having the Google Maps API key in our repository as a security vulnerability. ** Relevant ticket(s): * https://mitlibraries.atlassian.net/browse/pw-172 ** How does this address that need: * While we disagree that this represents a security vulnerability - the key is sent to all website users in order to load map assets - there is also no need to handle the key directly in our source code. This defines a theme settings field that will store this key going forward, which will also allow us to rotate the key more easily without a code change. * The access granted to our maps key has also been restricted, which results in less ability for users to spot the key (as happened here) and then probe its ability for related APIs that are not needed but were inadvertently authorized. ** Document any side effects to this change: * It is marginally easier for non-developers to manage this key now.
1 parent 6ef81c0 commit d938276

File tree

2 files changed

+142
-1
lines changed

2 files changed

+142
-1
lines changed

web/app/themes/mitlib-parent/functions.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@
2727
*/
2828
require_once( 'lib/news.php' );
2929

30+
/**
31+
* The theme relies upon an external provider (Google) to provide the map
32+
* tiles for the map of our locations. That integration is requires a key which
33+
* is managed on a dedicated dashboard.
34+
*/
35+
require_once( 'src/class-maps.php' );
36+
add_action( 'admin_init', array( 'Mitlib\Parent\Maps', 'settings' ) );
37+
add_action( 'admin_menu', array( 'Mitlib\Parent\Maps', 'init' ) );
38+
3039
/**
3140
* Define custom query params. Right now this is just the `v` parameter used by
3241
* the map template.
@@ -177,7 +186,7 @@ function setup_scripts_styles() {
177186

178187
wp_register_script( 'gldatepickerJS', get_template_directory_uri() . '/libs/datepicker/glDatePicker.min.js', array(), '2.0', true );
179188

180-
wp_register_script( 'googleMapsAPI', '//maps.googleapis.com/maps/api/js?key=AIzaSyDJg6fTKm3Pa_NfKEVAdyeRUbVs7zZm5Nw', array(), '1.7.0', true );
189+
wp_register_script( 'googleMapsAPI', '//maps.googleapis.com/maps/api/js?key=' . get_option( 'google_maps_key' ), array(), '1.7.0', true );
181190

182191
wp_register_script( 'jquery-cookie', get_template_directory_uri() . '/js/libs/jquery.cookie/jquery.cookie.js', array(), '1.3', true );
183192

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<?php
2+
/**
3+
* Class that defines a theme settings dashboard for a Google Maps integration.
4+
* This includes both the page and individual setting field.
5+
*
6+
* @package MITlib_Parent
7+
* @since 0.8
8+
*/
9+
10+
namespace Mitlib\Parent;
11+
12+
/**
13+
* Defines settings dashboard for maps integration. This class gets loaded and
14+
* hooked into from the theme's functions.php file.
15+
*/
16+
class Maps {
17+
/**
18+
* The required permission to access the admin page.
19+
*/
20+
const PERMS = 'manage_options';
21+
22+
/**
23+
* This defines the admin page which holds the settings management form.
24+
*/
25+
public static function init() {
26+
if ( current_user_can( self::PERMS ) ) {
27+
add_options_page(
28+
'Maps',
29+
'Map',
30+
self::PERMS,
31+
'mitlib-maps-dashboard',
32+
array( 'Mitlib\Parent\Maps', 'dashboard' )
33+
);
34+
}
35+
}
36+
37+
/**
38+
* This defines the content displayed on the admin page. It also receives the
39+
* submission of the web form on that page, and calls the update action when
40+
* needed.
41+
*/
42+
public static function dashboard() {
43+
// Confirm user capabilities before doing anything.
44+
if ( ! current_user_can( self::PERMS ) ) {
45+
return;
46+
}
47+
48+
// If the form has been posted, the update method handles that.
49+
$action = filter_input( INPUT_POST, 'action' );
50+
if ( ! empty( $action ) ) {
51+
self::update();
52+
}
53+
54+
// Finally, we render the form itself.
55+
echo '<div class="wrap">';
56+
echo '<h1>Maps settings</h1>';
57+
echo '<p>This form will update the Google Maps API key which grants us access to use their map assets on our locations page.</p>';
58+
echo '<p>This key is managed by the [email protected] user as part of the <a href="https://console.cloud.google.com/apis/credentials?project=api-project-260287310852">Google Cloud Platform</a>.</p>';
59+
echo '<form method="post" action="">';
60+
wp_nonce_field( 'custom_nonce_action', 'custom_nonce_field' );
61+
settings_fields( 'mitlib_parent_maps' );
62+
do_settings_sections( 'mitlib-maps-dashboard' );
63+
submit_button( 'Update maps settings' );
64+
echo '</form>';
65+
echo '</div>';
66+
}
67+
68+
/**
69+
* This is the general descriptive statement at the top of the settings form.
70+
* We don't use this, but the method needs to exist.
71+
*/
72+
public static function general() {
73+
echo '';
74+
}
75+
76+
/**
77+
* Field rendering callback for the Google Maps key setting.
78+
*/
79+
public static function google_maps_key_callback() {
80+
$google_maps_key = get_option( 'google_maps_key' );
81+
echo '<input type="text" name="google_maps_key" value="' . esc_attr( $google_maps_key ) . '" id="google_maps_key" size="60">';
82+
}
83+
84+
/**
85+
* Register the setting field which holds the Google maps key. This includes
86+
* creating a section, which is a bit overkill for only one setting, but here
87+
* we are.
88+
*/
89+
public static function settings() {
90+
register_setting( 'mitlib_parent_maps', 'google_maps_key' );
91+
92+
add_settings_section(
93+
'mitlib_parent_maps_general',
94+
'General settings',
95+
array( 'Mitlib\Parent\Maps', 'general' ),
96+
'mitlib-maps-dashboard'
97+
);
98+
99+
add_settings_field(
100+
'google_maps_key',
101+
'Google Maps API key',
102+
array( 'Mitlib\Parent\Maps', 'google_maps_key_callback' ),
103+
'mitlib-maps-dashboard',
104+
'mitlib_parent_maps_general',
105+
array(
106+
'label_for' => 'google_maps_key',
107+
'class' => 'mitlib_maps_row',
108+
)
109+
);
110+
}
111+
112+
/**
113+
* Update setting based on posted form information.
114+
*/
115+
public static function update() {
116+
check_admin_referer( 'custom_nonce_action', 'custom_nonce_field' );
117+
118+
if ( 'update' == filter_input( INPUT_POST, 'action' ) ) {
119+
$google_maps_key = '';
120+
121+
if ( filter_input( INPUT_POST, 'google_maps_key' ) ) {
122+
$google_maps_key = sanitize_text_field(
123+
wp_unslash( filter_input( INPUT_POST, 'google_maps_key' ) )
124+
);
125+
}
126+
127+
update_option( 'google_maps_key', $google_maps_key );
128+
}
129+
130+
echo( '<div class="updated"><p>The maps settings have been updated.</p></div>' );
131+
}
132+
}

0 commit comments

Comments
 (0)