settings = $settings; $this->initialize_hooks(); } public function initialize_hooks() { add_action('init', array($this, 'initialize_state')); // Authenticate with Clef is there is a valid OAuth code present add_action('authenticate', array($this, 'authenticate_clef'), 10, 3); // Disable password authentication according to settings add_action('wp_authenticate_user', array($this, 'disable_passwords')); // Clear logout hook if the user is logging in again add_filter('wp_authenticate_user', array($this, 'clear_logout_hook')); // Connect Clef account if logging in with a clef ID add_filter('wp_authenticate_user', array($this, 'connect_clef_account_on_login')); // Check if account was connected on login and if so flash a success message add_action('admin_notices', array($this, 'display_connect_clef_account_success')); // adds classes which hide login form if appropriate add_action('login_body_class', array($this, 'add_login_form_classes' )); // Render the login form with the Clef button no matter what add_action('login_form', array( $this, 'login_form' ) ); add_action('register_form', array( $this, 'register_form') ); add_filter('wp_login_failed', array($this, 'handle_login_failed')); add_action('login_enqueue_scripts', array($this, 'load_base_styles')); // Show an error message if there is an invite code but it is invalid add_filter('login_message', array($this, 'validate_invite')); // Disable password reset, according to settings add_filter('allow_password_reset', array($this, 'disable_password_reset'), 10, 2); // Redirect to an Clef onboarding page if a user logs in with an invite // code add_filter('login_redirect', array($this, 'redirect_if_invite_code'), 10, 3); // Allow the Clef button to be rendered anywhere add_action('clef_render_login_button', array($this, 'render_login_button'), 10, 4); add_shortcode('clef_render_login_button', array($this, 'shortcode_render_login_button')); if (defined('MEMBERSHIP_MASTER_ADMIN') && defined('MEMBERSHIP_SETACTIVATORAS_ADMIN')) { add_action('signup_hidden_fields', array($this, 'add_clef_login_button_to_wpmu')); add_action('bp_before_account_details_fields', array($this, 'add_clef_login_button_to_wpmu')); add_action('membership_popover_extend_registration_form', array($this, 'add_clef_login_button_to_wpmu')); add_action('signup_extra_fields', array($this, 'add_clef_login_button_to_wpmu')); add_action('membership_popover_extend_login_form', array($this, 'add_clef_login_button_to_wpmu')); } $this->apply_filter_and_action_fixes('plugins_loaded'); } public function add_clef_login_button_to_wpmu() { if ($this->settings->is_configured()) { $_REQUEST['redirect_to'] = $redirect_url = apply_filters('wdfb_registration_redirect_url', ''); do_action('clef_render_login_button'); } } public function load_base_styles() { $ident = ClefUtils::register_style('main'); wp_enqueue_style($ident); $ident = ClefUtils::register_script('login'); wp_enqueue_script($ident); if (!has_action('login_enqueue_scripts', 'wp_print_styles')) add_action('login_enqueue_scripts', 'wp_print_styles', 11); } public function redirect_if_invite_code($redirect_to, $request, $user) { if (isset($_REQUEST['clef_invite_code'])) { $invite_code = $_REQUEST['clef_invite_code']; $invite_email = base64_decode(ClefUtils::isset_GET('clef_invite_id')); $error = $this->validate_invite_code($invite_code, $invite_email); if (!$error) { return admin_url('admin.php?page=connect_clef_account'); } } return $redirect_to; } public function validate_invite($message) { $invite_code = ClefUtils::isset_GET('clef_invite_code'); $invite_email = base64_decode(ClefUtils::isset_GET('clef_invite_id')); $error = $this->validate_invite_code($invite_code, $invite_email); if ($invite_code && $error) { return '
' . $error . '
'; } else { return $message; } } public function login_form() { if($this->settings->is_configured()) { $redirect_url = $this->get_callback_url(); $passwords_disabled = $this->settings->get('clef_password_settings_force'); $override_key = ClefUtils::isset_GET('override'); if (!$this->is_valid_override_key($override_key)) { $override_key = null; } $invite_code = ClefUtils::isset_GET('clef_invite_code'); $invite_email_encoded = ClefUtils::isset_GET('clef_invite_id'); if (!$this->has_valid_invite_code()) { $invite_code = null; $invite_email = null; } else { $redirect_url = add_query_arg(array( 'invite_code' => $invite_code), $redirect_url); } $app_id = $this->settings->get( 'clef_settings_app_id' ); $clef_embedded = $this->settings->should_embed_clef_login(); if (ClefUtils::isset_GET('clefup') == 'true') $clef_embedded = false; echo ClefUtils::render_template('login.tpl', array( "passwords_disabled" => $passwords_disabled, "clef_embedded" => $clef_embedded, "override_key" => $override_key, "redirect_url" => $redirect_url, "invite_code" => $invite_code, "invite_email" => $invite_email_encoded, "clef_id" => (isset($this->clef_id_to_connect) ? $this->clef_id_to_connect : false), "app_id" => $app_id )); } } public function register_form() { if ($this->settings->is_configured() && $this->settings->registration_with_clef_is_allowed()) { echo ClefUtils::render_template('register.tpl', array( "redirect_url" => $this->get_callback_url(), "app_id" => $this->settings->get( 'clef_settings_app_id' ) )); } } public function shortcode_render_login_button($atts) { $app_id = isset($atts['app_id']) ? $atts['app_id'] : false; $redirect_url = isset($atts['redirect_url']) ? $atts['redirect_url'] : false; $embed = isset($atts['embed']) ? $atts['embed'] : false; $type = isset($atts['type']) ? $atts['type'] : "login"; ob_start(); $this->render_login_button($redirect_url, $app_id, $embed); $output = ob_get_contents(); ob_end_clean(); return $output; } public function render_login_button($redirect_url=false, $app_id=false, $embed=false, $type="login") { if (!$app_id) $app_id = $this->settings->get( 'clef_settings_app_id' ); if (!$redirect_url) $redirect_url = $this->get_callback_url(); echo ClefUtils::render_template('button.tpl', array( "app_id" => $app_id, "redirect_url" => $redirect_url, "embed" => $embed, "type" => $type, "custom" => array( "logo" => $this->settings->get('customization_logo'), "message" => $this->settings->get('customization_message') ) )); } public function handle_login_failed($errors) { if (isset($_POST['override'])) { // if the person submitted an override before, automatically // submit it for them the next time $_GET['override'] = $_POST['override']; } } private function is_valid_override_key($override_key) { $valid_key = $this->settings->get( 'clef_override_settings_key' ); $is_valid_override_key = (!empty($valid_key) && !empty($override_key) && $valid_key != '' && $override_key != '' && $override_key === $valid_key); return $is_valid_override_key; } private function validate_invite_code($incoming_invite_code, $email) { $generic_error_message = __("Sorry, that isn't a valid invite code.", "clef"); if (!$incoming_invite_code || !$email) { return $generic_error_message; } $user = get_user_by('email', $email); if (empty($user)) { return $generic_error_message; } return $this->validate_invite_code_for_user($incoming_invite_code, $user); } private function validate_invite_code_for_user($incoming_invite_code, $user) { $invite_code = get_user_meta($user->ID, 'clef_invite_code', true); $three_days_ago = time() - 3 * 24 * 60 * 60; if (empty($invite_code) || ($invite_code->created_at < $three_days_ago) || ($invite_code->code !== $incoming_invite_code)) { return __("Sorry, this invite link has expired. Please contact your administrator for a new one.", "clef"); } } public function add_login_form_classes($classes) { if (!$this->settings->is_configured()) return $classes; array_push($classes, 'clef-login-form'); $override_key = ClefUtils::isset_GET('override'); $valid_override_or_invite = $this->is_valid_override_key($override_key) || $this->has_valid_invite_code(); if ($valid_override_or_invite) { array_push($classes, 'clef-override-or-invite'); } if ($this->settings->get( 'clef_password_settings_force' )) { array_push($classes, 'clef-hidden'); } if (isset($this->clef_id_to_connect)) { array_push($classes, 'clef-auto-connect-account'); } if ($this->settings->should_embed_clef_login()) { array_push($classes, 'clef-login-form-embed'); } // used to show username and password form in worst case scenario // where javascript fails and on-page toggle fails $show_username_password_form = ClefUtils::isset_GET('clefup') == 'true'; if ($show_username_password_form) { array_push($classes, 'clef-show-username-password'); } return $classes; } private function has_valid_invite_code() { if (!isset($_REQUEST['clef_invite_code']) || !isset($_REQUEST['clef_invite_id'])) { return false; } $incoming_invite_code = $_REQUEST['clef_invite_code']; $invite_email = base64_decode($_REQUEST['clef_invite_id']); if (!$incoming_invite_code || !$invite_email) { return false; } $error = $this->validate_invite_code($incoming_invite_code, $invite_email); return !$error; } public function disable_passwords($user) { if (isset($_POST['override']) && $this->is_valid_override_key($_POST['override'])) { return $user; } if ($this->has_valid_invite_code()) { return $user; } $disabled_for_user = $this->settings->passwords_are_disabled_for_user($user); $disabled_for_xml_rpc = !(defined('XMLRPC_REQUEST') && XMLRPC_REQUEST && $this->settings->xml_passwords_enabled()); if ($disabled_for_user && $disabled_for_xml_rpc) { add_filter('xmlrpc_login_error', array($this, "return_xml_error_message")); return new WP_Error('passwords_disabled', __("Passwords have been disabled for this user.", "clef")); } else { return $user; } } public function authenticate_clef($user, $username, $password) { if ( isset( $_REQUEST['clef'] ) && isset( $_REQUEST['code'] ) ) { $this->apply_filter_and_action_fixes("authenticate"); // Authenticate try { $info = ClefUtils::exchange_oauth_code_for_info($_REQUEST['code'], $this->settings); } catch (LoginException $e) { return new WP_Error('clef', $e->getMessage()); } catch (ClefStateException $e) { return new WP_Error('clef', $e->getMessage()); } $clef_id = $info->id; $email = isset($info->email) ? $info->email : ""; $first_name = isset($info->first_name) ? $info->first_name : ""; $last_name = isset($info->last_name) ? $info->last_name : ""; $users = get_users(array('meta_key' => 'clef_id', 'meta_value' => $clef_id, 'blog_id' => false)); if ($users) { // already have a user with this clef_id $user = $users[0]; } else { $user = get_user_by('email', $email); if (!$user) { if (get_option('users_can_register') && $this->settings->registration_with_clef_is_allowed()) { // Users can register, so create a new user $id = wp_create_user($email, wp_generate_password(16, FALSE), $email); if(is_wp_error($id)) { return new WP_Error( 'clef', __("An error occurred when creating your new account: ", 'clef') . $id->get_error_message() ); } $user = get_user_by('id', $id ); } else { $this->clef_id_to_connect = $clef_id; return new WP_Error( 'clef', __("There's no WordPress user connected to your Clef account.

Log in with your standard username and password to automatically connect your Clef account now.", 'clef') ); } } ClefUtils::associate_clef_id($clef_id, $user->ID); } do_action('clef_login', $user->ID); // Log in the user $session = ClefSession::start(); $session->set('logged_in_at', time()); return $user; } else { return $user; } } public function disable_password_reset($allow, $user_id) { $user = get_user_by('id', (int) $user_id); return !$this->settings->passwords_are_disabled_for_user($user); } public function clear_logout_hook($user) { $session = ClefSession::start(); if ($session->get('logged_in_at')) { $session->set('logged_in_at', null); } return $user; } public function connect_clef_account_on_login($user) { if (ClefUtils::isset_POST('clef_id') && $user && !is_wp_error($user)) { ClefUtils::associate_clef_id(ClefUtils::isset_POST('clef_id'), $user->ID); $session = ClefSession::start(); $session->set('clef_account_connected_on_login', true); $session->set('logged_in_at', time()); } return $user; } public function display_connect_clef_account_success() { $session = ClefSession::start(); if ($session->get('clef_account_connected_on_login')) { $session->set('clef_account_connected_on_login', null); ?>
Clef

Your Clef account has been connected!', 'clef'); ?>

'true'), wp_login_url()); # add redirect to if it exists if (isset($_REQUEST['redirect_to']) && $_REQUEST['redirect_to'] != '') { $url = add_query_arg( array('redirect_to' => urlencode($_REQUEST['redirect_to'])), $url ); } if (isset($_REQUEST['interim-login'])) { $url = add_query_arg(array('interim-login' => 1), $url); } return $url; } public function initialize_state() { ClefUtils::initialize_state(); } public static function start($settings) { if (!isset(self::$instance) || self::$instance === null || defined('CLEF_TESTING')) { self::$instance = new self($settings); } return self::$instance; } } ?>