@ -2,362 +2,370 @@
class OpenID_Connect_Generic_Settings {
class OpenID_Connect_Generic_Settings {
// local copy of the settings provided by the base plugin
// local copy of the settings provided by the base plugin
private $settings = array();
private $settings = array();
// The controlled list of settings & associated
// The controlled list of settings & associated
// defined during construction for i18n reasons
// defined during construction for i18n reasons
private $settings_fields = array();
private $settings_fields = array();
// options page slug
// options page slug
private $options_page_name = 'openid-connect-generic-settings';
private $options_page_name = 'openid-connect-generic-settings';
// options page settings group name
// options page settings group name
private $settings_field_group = '';
private $settings_field_group = '';
/**
/**
* @param $settings
* @param $settings
*/
*/
function __construct( $settings ){
function __construct( $settings ) {
$this->settings = $settings;
$this->settings = $settings;
$this->settings_field_group = OPENID_CONNECT_GENERIC_SETTINGS_NAME . '-group';
$this->settings_field_group = OPENID_CONNECT_GENERIC_SETTINGS_NAME . '-group';
// add our options page the the admin menu
// add our options page the the admin menu
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
// register our settings
// register our settings
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
/*
/*
* Simple settings fields simply have:
* Simple settings fields simply have:
*
*
* - title
* - title
* - description
* - description
* - type ( checkbox | text | select )
* - type ( checkbox | text | select )
* - section - settings/option page section ( client_settings | authorization_settings )
* - section - settings/option page section ( client_settings | authorization_settings )
* - example (optional example will appear beneath description and be wrapped in < code > )
* - example (optional example will appear beneath description and be wrapped in < code > )
*/
*/
$fields = array(
$fields = array(
'login_type' => array(
'login_type' => array(
'title' => __('Login Type'),
'title' => __( 'Login Type' ),
'description' => __('Select how the client (login form) should provide login options.'),
'description' => __( 'Select how the client (login form) should provide login options.' ),
'type' => 'select',
'type' => 'select',
'options' => array(
'options' => array(
'button' => __('OpenID Connect button on login form'),
'button' => __( 'OpenID Connect button on login form' ),
'auto' => __('Auto Login - SSO'),
'auto' => __( 'Auto Login - SSO' ),
),
),
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'ep_login' => array(
'ep_login' => array(
'title' => __('Login Endpoint URL'),
'title' => __( 'Login Endpoint URL' ),
'description' => __('Identify provider authorization endpoint.'),
'description' => __( 'Identify provider authorization endpoint.' ),
'example' => 'https://example.com/oauth2/authorize',
'example' => 'https://example.com/oauth2/authorize',
'type' => 'text',
'type' => 'text',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'ep_token' => array(
'ep_token' => array(
'title' => __('Token Validation Endpoint URL'),
'title' => __( 'Token Validation Endpoint URL' ),
'description' => __('Identify provider token endpoint.'),
'description' => __( 'Identify provider token endpoint.' ),
'example' => 'https://example.com/oauth2/token',
'example' => 'https://example.com/oauth2/token',
'type' => 'text',
'type' => 'text',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'ep_userinfo' => array(
'ep_userinfo' => array(
'title' => __('Userinfo Endpoint URL'),
'title' => __( 'Userinfo Endpoint URL' ),
'description' => __('Identify provider User information endpoint.'),
'description' => __( 'Identify provider User information endpoint.' ),
'example' => 'https://example.com/oauth2/UserInfo',
'example' => 'https://example.com/oauth2/UserInfo',
'type' => 'text',
'type' => 'text',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'no_sslverify' => array(
'no_sslverify' => array(
'title' => __('Disable SSL Verify'),
'title' => __( 'Disable SSL Verify' ),
'description' => __('Do not require SSL verification during authorization. The OAuth extension uses curl to make the request. By default CURL will generally verify the SSL certificate to see if its valid an issued by an accepted CA. This setting disabled that verification.'),
'description' => __( 'Do not require SSL verification during authorization. The OAuth extension uses curl to make the request. By default CURL will generally verify the SSL certificate to see if its valid an issued by an accepted CA. This setting disabled that verification.' ),
'type' => 'checkbox',
'type' => 'checkbox',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'client_id' => array(
'client_id' => array(
'title' => __('Client ID'),
'title' => __( 'Client ID' ),
'description' => __('The ID this client will be recognized as when connecting the to Identity provider server.'),
'description' => __( 'The ID this client will be recognized as when connecting the to Identity provider server.' ),
'example' => 'my-wordpress-client-id',
'example' => 'my-wordpress-client-id',
'type' => 'text',
'type' => 'text',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'client_secret' => array(
'client_secret' => array(
'title' => __('Client Secret Key'),
'title' => __( 'Client Secret Key' ),
'description' => __('Arbitrary secret key the server expects from this client. Can be anything, but should be very unique.'),
'description' => __( 'Arbitrary secret key the server expects from this client. Can be anything, but should be very unique.' ),
'type' => 'text',
'type' => 'text',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'scope' => array(
'scope' => array(
'title' => __('OpenID Scope'),
'title' => __( 'OpenID Scope' ),
'description' => __('Space separated list of scopes this client should access.'),
'description' => __( 'Space separated list of scopes this client should access.' ),
'example' => 'email profile openid',
'example' => 'email profile openid',
'type' => 'text',
'type' => 'text',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'identity_key' => array(
'identity_key' => array(
'title' => __('Identity Key'),
'title' => __( 'Identity Key' ),
'description' => __('Where in the response array to find the identification data. When in doubt, use "sub".'),
'description' => __( 'Where in the response array to find the identification data. When in doubt, use "sub".' ),
'example' => 'sub',
'example' => 'sub',
'type' => 'text',
'type' => 'text',
'section' => 'client_settings',
'section' => 'client_settings',
),
),
'allowed_regex' => array(
'allowed_regex' => array(
'title' => __('Authorization Regex'),
'title' => __( 'Authorization Regex' ),
'description' => __('Provide a regular expression that enforces your expectations concerning the identity value returned from the IDP.'),
'description' => __( 'Provide a regular expression that enforces your expectations concerning the identity value returned from the IDP.' ),
'type' => 'text',
'type' => 'text',
'section' => 'authorization_settings',
'section' => 'authorization_settings',
),
),
'enforce_privacy' => array(
'enforce_privacy' => array(
'title' => __('Enforce Privacy'),
'title' => __( 'Enforce Privacy' ),
'description' => __('Require users be logged in to see the site.'),
'description' => __( 'Require users be logged in to see the site.' ),
'type' => 'checkbox',
'type' => 'checkbox',
'section' => 'authorization_settings',
'section' => 'authorization_settings',
),
),
'enable_logging' => array(
'enable_logging' => array(
'title' => __('Enable Logging'),
'title' => __( 'Enable Logging' ),
'description' => __('Very simple log messages for debugging purposes.'),
'description' => __( 'Very simple log messages for debugging purposes.' ),
'type' => 'checkbox',
'type' => 'checkbox',
'section' => 'log_settings',
'section' => 'log_settings',
),
),
'log_limit' => array(
'log_limit' => array(
'title' => __('Log Limit'),
'title' => __( 'Log Limit' ),
'description' => __('Number of items to keep in the log. These logs are stored as an option in the database, so space is limited.'),
'description' => __( 'Number of items to keep in the log. These logs are stored as an option in the database, so space is limited.' ),
'type' => 'number',
'type' => 'number',
'section' => 'log_settings',
'section' => 'log_settings',
),
),
);
);
$fields = apply_filters( 'openid-connect-generic-settings-fields', $fields );
$fields = apply_filters( 'openid-connect-generic-settings-fields', $fields );
// some simple pre-processing
// some simple pre-processing
foreach ( $fields as $key => & $field ) {
foreach ( $fields as $key => & $field ) {
$field['key'] = $key;
$field['key'] = $key;
$field['name'] = OPENID_CONNECT_GENERIC_SETTINGS_NAME . '[' . $key . ']';
$field['name'] = OPENID_CONNECT_GENERIC_SETTINGS_NAME . '[' . $key . ']';
}
}
// allow alterations of the fields
// allow alterations of the fields
$this->settings_fields = $fields;
$this->settings_fields = $fields;
}
}
/**
/**
* Implements hook admin_menu to add our options/settings page to the
* Implements hook admin_menu to add our options/settings page to the
* dashboard menu
* dashboard menu
*/
*/
public function admin_menu() {
public function admin_menu() {
add_options_page(
add_options_page(
__('OpenID Connect - Generic Client'),
__( 'OpenID Connect - Generic Client' ),
__('OpenID Connect Client'),
__( 'OpenID Connect Client' ),
'manage_options',
'manage_options',
$this->options_page_name,
$this->options_page_name,
array( $this, 'settings_page') );
array( $this, 'settings_page' ) );
}
}
/**
/**
* Implements hook admin_init to register our settings
* Implements hook admin_init to register our settings
*/
*/
public function admin_init() {
public function admin_init() {
register_setting( $this->settings_field_group, OPENID_CONNECT_GENERIC_SETTINGS_NAME, array( $this, 'sanitize_settings' ) );
register_setting( $this->settings_field_group, OPENID_CONNECT_GENERIC_SETTINGS_NAME, array(
$this,
add_settings_section( 'client_settings',
'sanitize_settings'
__('Client Settings'),
) );
array( $this, 'client_settings_description' ),
$this->options_page_name
add_settings_section( 'client_settings',
);
__( 'Client Settings' ),
array( $this, 'client_settings_description' ),
add_settings_section( 'authorization_settings',
$this->options_page_name
__('Authorization Settings'),
);
array( $this, 'authorization_settings_description' ),
$this->options_page_name
add_settings_section( 'authorization_settings',
);
__( 'Authorization Settings' ),
array( $this, 'authorization_settings_description' ),
add_settings_section( 'log_settings',
$this->options_page_name
__('Log Settings'),
);
array( $this, 'log_settings_description' ),
$this->options_page_name
add_settings_section( 'log_settings',
);
__( 'Log Settings' ),
array( $this, 'log_settings_description' ),
// preprocess fields and add them to the page
$this->options_page_name
foreach ( $this->settings_fields as $key => $field ) {
);
// make sure each key exists in the settings array
if ( ! isset( $this->settings[ $key ] ) ){
// preprocess fields and add them to the page
$this->settings[ $key ] = null;
foreach ( $this->settings_fields as $key => $field ) {
}
// make sure each key exists in the settings array
if ( ! isset( $this->settings[ $key ] ) ) {
// determine appropriate output callback
$this->settings[ $key ] = NULL;
switch ( $field['type'] ) {
}
case 'checkbox':
$callback = 'do_checkbox';
// determine appropriate output callback
break;
switch ( $field['type'] ) {
case 'checkbox':
case 'select':
$callback = 'do_checkbox';
$callback = 'do_select';
break;
break;
case 'select':
case 'text':
$callback = 'do_select';
default:
break;
$callback = 'do_text_field';
break;
case 'text':
}
default:
$callback = 'do_text_field';
// add the field
break;
add_settings_field( $key, $field['title'],
}
array( $this, $callback ),
$this->options_page_name,
// add the field
$field['section'],
add_settings_field( $key, $field['title'],
$field
array( $this, $callback ),
);
$this->options_page_name,
}
$field['section'],
}
$field
);
/**
}
* Sanitization callback for settings/option page
}
*
* @param $input - submitted settings values
/**
* @return array
* Sanitization callback for settings/option page
*/
*
public function sanitize_settings( $input ) {
* @param $input - submitted settings values
$options = array();
*
* @return array
// loop through settings fields to control what we're saving
*/
foreach ( $this->settings_fields as $key => $field ) {
public function sanitize_settings( $input ) {
if ( isset( $input[ $key ] ) ){
$options = array();
$options[ $key ] = sanitize_text_field( trim( $input[ $key ] ) );
}
// loop through settings fields to control what we're saving
else {
foreach ( $this->settings_fields as $key => $field ) {
$options[ $key ] = '';
if ( isset( $input[ $key ] ) ) {
}
$options[ $key ] = sanitize_text_field( trim( $input[ $key ] ) );
}
}
else {
return $options;
$options[ $key ] = '';
}
}
}
/**
* Output the options/settings page
return $options;
*/
}
public function settings_page() {
?>
/**
< div class = "wrap" >
* Output the options/settings page
< h2 > <?php print esc_html ( get_admin_page_title () ); ?> </ h2 >
*/
< form method = "post" action = "options.php" >
public function settings_page() {
<?php
?>
settings_fields( $this->settings_field_group );
< div class = "wrap" >
do_settings_sections( $this->options_page_name );
< h2 > <?php print esc_html ( get_admin_page_title () ); ?> </ h2 >
submit_button();
?>
< form method = "post" action = "options.php" >
< / form >
<?php
settings_fields( $this->settings_field_group );
< h4 > <?php _e ( 'Notes' ); ?> </ h4 >
do_settings_sections( $this->options_page_name );
< p class = "description" >
submit_button();
< strong > <?php _e ( 'Redirect URI' ); ?> </ strong > < code > <?php print admin_url ( 'admin-ajax.php?action=openid-connect-authorize' ); ?> </ code >
?>
< / p >
< / form >
<?php
< h4 > <?php _e ( 'Notes' ); ?> </ h4 >
$logs = get_option( 'openid_connect_generic_logs', array() );
< p class = "description" >
if ( !empty( $logs ) ) {
< strong > <?php _e ( 'Redirect URI' ); ?> </ strong >
?>
< code > <?php print admin_url ( 'admin-ajax.php?action=openid-connect-authorize' ); ?> </ code >
< h4 > <?php _e ( 'Logs' ); ?> </ h4 >
< / p >
< table class = "wp-list-table widefat fixed striped posts" >
< thead >
<?php
< th > Type< / th >
$logs = get_option( 'openid_connect_generic_logs', array() );
< th > Date< / th >
< th > User< / th >
if ( ! empty( $logs ) ) {
< th style = "width: 65%;" > Data< / th >
?>
< / thead >
< h4 > <?php _e ( 'Logs' ); ?> </ h4 >
< tbody >
< table class = "wp-list-table widefat fixed striped posts" >
<?php foreach ( $logs as $log ){ ?>
< thead >
< tr >
< th > Type< / th >
< td > <?php print $log [ 'type' ]; ?> </ td >
< th > Date< / th >
< td > <?php print date ( 'Y-m-d H:i:s' , $log [ 'time' ] ); ?> </ td >
< th > User< / th >
< td > <?php print ( $log [ 'user_ID' ] ) ? get_userdata ( $log [ 'user_ID' ] ) -> user_login : 'anonymous' ; ?> </ td >
< th style = "width: 65%;" > Data< / th >
< td > <?php print '<pre style="margin:0;">' . print_r ( $log [ 'data' ], 1 ) . '</pre>' ; ?> </ td >
< / thead >
< / tr >
< tbody >
<?php } ?>
<?php foreach ( $logs as $log ) { ?>
< / tbody >
< tr >
< / table >
< td > <?php print $log [ 'type' ]; ?> </ td >
<?php
< td > <?php print date ( 'Y-m-d H:i:s' , $log [ 'time' ] ); ?> </ td >
}
< td > <?php print ( $log [ 'user_ID' ] ) ? get_userdata ( $log [ 'user_ID' ] ) -> user_login : 'anonymous' ; ?> </ td >
?>
< td > <?php print '<pre style="margin:0;">' . print_r ( $log [ 'data' ], 1 ) . '</pre>' ; ?> </ td >
< / div >
< / tr >
<?php
<?php } ?>
}
< / tbody >
< / table >
/**
<?php
* Output a standard text field
}
*
?>
* @param $field
< / div >
*/
<?php
public function do_text_field( $field ) {
}
?>
< input type = " <?php print esc_attr ( $field [ 'type' ] ); ?> "
/**
id="<?php print esc_attr ( $field [ 'key' ] ); ?> "
* Output a standard text field
class="large-text"
*
name="<?php print esc_attr ( $field [ 'name' ] ); ?> "
* @param $field
value="<?php print esc_attr ( $this -> settings [ $field [ 'key' ] ] ); ?> ">
*/
<?php
public function do_text_field( $field ) {
$this->do_field_description( $field );
?>
}
< input type = " <?php print esc_attr ( $field [ 'type' ] ); ?> "
id="<?php print esc_attr ( $field [ 'key' ] ); ?> "
/**
class="large-text"
* Output a checkbox for a boolean setting
name="<?php print esc_attr ( $field [ 'name' ] ); ?> "
* - hidden field is default value so we don't have to check isset() on save
value="<?php print esc_attr ( $this -> settings [ $field [ 'key' ] ] ); ?> ">
*
<?php
* @param $field
$this->do_field_description( $field );
*/
}
public function do_checkbox( $field ) {
?>
/**
< input type = "hidden" name = " <?php print esc_attr ( $field [ 'name' ] ); ?> " value = "0" >
* Output a checkbox for a boolean setting
< input type = "checkbox"
* - hidden field is default value so we don't have to check isset() on save
id="<?php print esc_attr ( $field [ 'key' ] ); ?> "
*
name="<?php print esc_attr ( $field [ 'name' ] ); ?> "
* @param $field
value="1"
*/
<?php checked ( $this -> settings [ $field [ 'key' ] ] , 1 ); ?> >
public function do_checkbox( $field ) {
<?php
?>
$this->do_field_description( $field );
< input type = "hidden" name = " <?php print esc_attr ( $field [ 'name' ] ); ?> " value = "0" >
}
< input type = "checkbox"
id="<?php print esc_attr ( $field [ 'key' ] ); ?> "
/**
name="<?php print esc_attr ( $field [ 'name' ] ); ?> "
* @param $field
value="1"
*/
<?php checked ( $this -> settings [ $field [ 'key' ] ], 1 ); ?> >
function do_select( $field ) {
<?php
$current_value = ( $this->settings[ $field['key'] ] ? $this->settings[ $field['key'] ] : '');
$this->do_field_description( $field );
?>
}
< select name = " <?php print esc_attr ( $field [ 'name' ] ); ?> " >
<?php foreach ( $field [ 'options' ] as $value => $text ) : ?>
/**
< option value = " <?php print esc_attr ( $value ); ?> " <?php selected ( $value , $current_value ); ?> > <?php print esc_html ( $text ); ?> </ option >
* @param $field
<?php endforeach ; ?>
*/
< / select >
function do_select( $field ) {
<?php
$current_value = ( $this->settings[ $field['key'] ] ? $this->settings[ $field['key'] ] : '' );
$this->do_field_description( $field );
?>
}
< select name = " <?php print esc_attr ( $field [ 'name' ] ); ?> " >
<?php foreach ( $field [ 'options' ] as $value => $text ) : ?>
/**
< option value = " <?php print esc_attr ( $value ); ?> " <?php selected ( $value , $current_value ); ?> > <?php print esc_html ( $text ); ?> </ option >
* Simply output the field description, and example if present
<?php endforeach ; ?>
*
< / select >
* @param $field
<?php
*/
$this->do_field_description( $field );
public function do_field_description( $field ){
}
?>
< p class = "description" >
/**
<?php print $field [ 'description' ]; ?>
* Simply output the field description, and example if present
<?php if ( isset ( $field [ 'example' ] ) ) : ?>
*
< br />< strong > <?php _e ( 'Example' ); ?> : </ strong >< code > <?php print $field [ 'example' ]; ?> </ code >
* @param $field
<?php endif ; ?>
*/
< / p >
public function do_field_description( $field ) {
<?php
?>
}
< p class = "description" >
<?php print $field [ 'description' ]; ?>
public function client_settings_description() {
<?php if ( isset ( $field [ 'example' ] ) ) : ?>
_e('Enter your OpenID Connect identity provider settings');
< br />< strong > <?php _e ( 'Example' ); ?> : </ strong >
}
< code > <?php print $field [ 'example' ]; ?> </ code >
<?php endif ; ?>
public function authorization_settings_description() {
< / p >
_e('Control the authorization mechanics of the site');
<?php
}
}
public function log_settings_description() {
public function client_settings_description() {
_e('Log information about login attempts through OpenID Connect Generic');
_e( 'Enter your OpenID Connect identity provider settings' );
}
}
public function authorization_settings_description() {
_e( 'Control the authorization mechanics of the site' );
}
public function log_settings_description() {
_e( 'Log information about login attempts through OpenID Connect Generic' );
}
}
}