Skip to content
Snippets Groups Projects
Verified Commit 09502f0b authored by Andrei Mondoc's avatar Andrei Mondoc Committed by Kevin Cristiano
Browse files

log in and sync wp user before dispatching rest response

parent 4acd14db
No related branches found
No related tags found
No related merge requests found
......@@ -451,7 +451,7 @@ class Rest extends Base {
* @param string $param
* @return bool
*/
protected function is_valid_json( $param ) {
public function is_valid_json( $param ) {
$param = json_decode( $param, true );
......@@ -467,7 +467,7 @@ class Rest extends Base {
* @since 0.1
* @return bool $is_valid_site_key
*/
private function is_valid_site_key() {
public function is_valid_site_key() {
return \CRM_Utils_System::authenticateKey( false );
......@@ -480,7 +480,7 @@ class Rest extends Base {
* @param WP_REST_Resquest $request
* @return bool $is_valid_api_key
*/
private function is_valid_api_key( $request ) {
public function is_valid_api_key( $request ) {
$api_key = $request->get_param( 'api_key' );
......@@ -488,73 +488,9 @@ class Rest extends Base {
$contact_id = \CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact', $api_key, 'id', 'api_key' );
// validate contact and login
if ( $contact_id ) {
if ( ! $contact_id ) return false;
$wp_user = $this->get_wp_user( $contact_id );
$this->do_user_login( $wp_user );
return true;
}
return false;
}
/**
* Get WordPress user data.
*
* @since 0.1
* @param int $contact_id The contact id
* @return bool|WP_User $user The WordPress user data
*/
protected function get_wp_user( int $contact_id ) {
try {
// Get CiviCRM domain group ID from constant, if set.
$domain_id = defined( 'CIVICRM_DOMAIN_ID' ) ? CIVICRM_DOMAIN_ID : 0;
// If this fails, get it from config.
if ( $domain_id === 0 ) {
$domain_id = \CRM_Core_Config::domainID();
}
// Call API.
$uf_match = civicrm_api3( 'UFMatch', 'getsingle', [
'contact_id' => $contact_id,
'domain_id' => $domain_id,
] );
} catch ( \CiviCRM_API3_Exception $e ) {
return $this->civi_rest_error( $e->getMessage() );
}
$wp_user = get_userdata( $uf_match['uf_id'] );
return $wp_user;
}
/**
* Logs in the WordPress user, needed to respect CiviCRM ACL and permissions.
*
* @since 0.1
* @param WP_User $user
*/
protected function do_user_login( \WP_User $user ) {
if ( is_user_logged_in() ) return;
wp_set_current_user( $user->ID, $user->user_login );
wp_set_auth_cookie( $user->ID );
do_action( 'wp_login', $user->user_login, $user );
return true;
}
......
......@@ -56,6 +56,17 @@ class Plugin {
civi_wp()->initialize();
// rest calls need a wp user, do login
if ( false !== strpos( $request->get_route(), 'rest' ) ) {
$logged_in_wp_user = $this->do_user_login( $request );
// return error
if ( is_wp_error( $logged_in_wp_user ) ) {
return $logged_in_wp_user;
}
}
}
return $result;
......@@ -201,4 +212,168 @@ class Plugin {
}
/**
* Performs the necessary checks and
* data retrieval to login a WordPress user.
*
* @since 0.1
* @param \WP_REST_Request $request The request
* @return \WP_User|\WP_Error|void $logged_in_wp_user The logged in WordPress user object, \Wp_Error, or nothing
*/
public function do_user_login( $request ) {
/**
* Filter and opportunity to bypass
* the default user login.
*
* @since 0.1
* @param bool $login
*/
$logged_in = apply_filters( 'civi_wp_rest/plugin/do_user_login', false, $request );
if ( $logged_in ) return;
// default login based on contact's api_key
if ( ! ( new Controller\Rest )->is_valid_api_key( $request ) ) {
return new \WP_Error(
'civicrm_rest_api_error',
__( 'Missing or invalid param "api_key".', 'civicrm' )
);
}
$contact_id = \CRM_Core_DAO::getFieldValue(
'CRM_Contact_DAO_Contact',
$request->get_param( 'api_key' ),
'id',
'api_key'
);
$wp_user = $this->get_wp_user( $contact_id );
if ( is_wp_error( $wp_user ) ) {
return $wp_user;
}
return $this->login_wp_user( $wp_user, $request );
}
/**
* Get WordPress user data.
*
* @since 0.1
* @param int $contact_id The contact id
* @return WP_User|WP_Error $user The WordPress user data or WP_Error object
*/
public function get_wp_user( int $contact_id ) {
try {
// Call API.
$uf_match = civicrm_api3( 'UFMatch', 'getsingle', [
'contact_id' => $contact_id,
'domain_id' => $this->get_civi_domain_id(),
] );
} catch ( \CiviCRM_API3_Exception $e ) {
return new \WP_Error(
'civicrm_rest_api_error',
__( 'A WordPress user must be associated with the contact for the provided API key.', 'civicrm' )
);
}
// filter uf_match
add_filter( 'civi_wp_rest/plugin/uf_match', function() use ( $uf_match ) {
return ! empty( $uf_match ) ? $uf_match : null;
} );
return get_userdata( $uf_match['uf_id'] );
}
/**
* Logs in the WordPress user, and
* syncs it with it's CiviCRM contact.
*
* @since 0.1
* @param \WP_User $user The WordPress user object
* @param \WP_REST_Request|null $request The request object or null
* @return \WP_User|void $wp_user The logged in WordPress user object or nothing
*/
public function login_wp_user( \WP_User $wp_user, $request = null ) {
/**
* Filter the user about to be logged in.
*
* @since 0.1
* @param \WP_User $user The WordPress user object
* @param \WP_REST_Request|null $request The request object or null
*/
$wp_user = apply_filters( 'civi_wp_rest/plugin/wp_user_login', $wp_user, $request );
wp_set_current_user( $wp_user->ID, $wp_user->user_login );
wp_set_auth_cookie( $wp_user->ID );
do_action( 'wp_login', $wp_user->user_login, $wp_user );
$this->set_civi_user_session( $wp_user );
return $wp_user;
}
/**
* Sets the necessary user
* session variables for CiviCRM.
*
* @since 0.1
* @param \WP_User $wp_user The WordPress user
* @return void
*/
public function set_civi_user_session( $wp_user ): void {
$uf_match = apply_filters( 'civi_wp_rest/plugin/uf_match', null );
if ( ! $uf_match ) {
// Call API.
$uf_match = civicrm_api3( 'UFMatch', 'getsingle', [
'uf_id' => $wp_user->ID,
'domain_id' => $this->get_civi_domain_id(),
] );
}
// Set necessary session variables.
$session = \CRM_Core_Session::singleton();
$session->set( 'ufID', $wp_user->ID );
$session->set( 'userID', $uf_match['contact_id'] );
$session->set( 'ufUniqID', $uf_match['uf_name'] );
}
/**
* Retrieves the CiviCRM domain_id.
*
* @since 0.1
* @return int $domain_id The domain id
*/
public function get_civi_domain_id(): int {
// Get CiviCRM domain group ID from constant, if set.
$domain_id = defined( 'CIVICRM_DOMAIN_ID' ) ? CIVICRM_DOMAIN_ID : 0;
// If this fails, get it from config.
if ( $domain_id === 0 ) {
$domain_id = \CRM_Core_Config::domainID();
}
return $domain_id;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment