Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+83 -34
View File
@@ -11,7 +11,7 @@
namespace IPS\Login\Handler;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -114,24 +114,37 @@ class _LDAP extends \IPS\Login\Handler
)
) );
$nameChangesDisabled = array();
if ( $forceNameHandler = static::handlerHasForceSync( 'name', $this ) )
{
$nameChangesDisabled[] = 'force';
\IPS\Member::loggedIn()->language()->words['login_update_changes_yes_name_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'login_update_changes_yes_disabled', FALSE, array( 'sprintf' => $forceNameHandler->_title ) );
}
$emailChangesDisabled = array();
if ( $forceEmailHandler = static::handlerHasForceSync( 'email', $this ) )
{
$emailChangesDisabled[] = 'force';
\IPS\Member::loggedIn()->language()->words['login_update_changes_yes_email_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'login_update_changes_yes_disabled', FALSE, array( 'sprintf' => $forceEmailHandler->_title ) );
}
$return['update_name_changes_inc_optional'] = new \IPS\Helpers\Form\Radio( 'login_update_name_changes_inc_optional', isset( $this->settings['update_name_changes'] ) ? $this->settings['update_name_changes'] : 'disabled', FALSE, array( 'options' => array(
'force' => 'login_update_changes_yes',
'force' => 'login_update_changes_yes_name',
'optional' => 'login_update_changes_optional',
'disabled' => 'login_update_changes_no',
) ), NULL, NULL, NULL, 'login_update_name_changes_inc_optional' );
), 'disabled' => $nameChangesDisabled ), NULL, NULL, NULL, 'login_update_name_changes_inc_optional' );
$return['update_name_changes_no_optional'] = new \IPS\Helpers\Form\Radio( 'login_update_name_changes_no_optional', ( isset( $this->settings['update_name_changes'] ) and $this->settings['update_name_changes'] != 'optional' ) ? $this->settings['update_name_changes'] : 'disabled', FALSE, array( 'options' => array(
'force' => 'login_update_changes_yes',
'force' => 'login_update_changes_yes_name',
'disabled' => 'login_update_changes_no',
) ), NULL, NULL, NULL, 'login_update_name_changes_no_optional' );
), 'disabled' => $nameChangesDisabled ), NULL, NULL, NULL, 'login_update_name_changes_no_optional' );
$return['update_email_changes_inc_optional'] = new \IPS\Helpers\Form\Radio( 'login_update_email_changes_inc_optional', isset( $this->settings['update_email_changes'] ) ? $this->settings['update_email_changes'] : 'force', FALSE, array( 'options' => array(
'force' => 'login_update_changes_yes',
'force' => 'login_update_changes_yes_email',
'optional' => 'login_update_changes_optional',
'disabled' => 'login_update_changes_no',
) ), NULL, NULL, NULL, 'login_update_email_changes_inc_optional' );
), 'disabled' => $emailChangesDisabled ), NULL, NULL, NULL, 'login_update_email_changes_inc_optional' );
$return['update_email_changes_no_optional'] = new \IPS\Helpers\Form\Radio( 'login_update_email_changes_no_optional', ( isset( $this->settings['update_email_changes'] ) and $this->settings['update_email_changes'] != 'optional' ) ? $this->settings['update_email_changes'] : 'force', FALSE, array( 'options' => array(
'force' => 'login_update_changes_yes',
'force' => 'login_update_changes_yes_email',
'disabled' => 'login_update_changes_no',
) ), NULL, NULL, NULL, 'login_update_email_changes_no_optional' );
), 'disabled' => $emailChangesDisabled ), NULL, NULL, NULL, 'login_update_email_changes_no_optional' );
\IPS\Member::loggedIn()->language()->words['login_update_name_changes_inc_optional'] = \IPS\Member::loggedIn()->language()->addToStack('login_update_name_changes');
\IPS\Member::loggedIn()->language()->words['login_update_name_changes_no_optional'] = \IPS\Member::loggedIn()->language()->addToStack('login_update_name_changes');
\IPS\Member::loggedIn()->language()->words['login_update_email_changes_inc_optional'] = \IPS\Member::loggedIn()->language()->addToStack('login_update_email_changes');
@@ -179,9 +192,9 @@ class _LDAP extends \IPS\Login\Handler
*/
public function testSettings()
{
if ( !extension_loaded('ldap') )
if ( !\extension_loaded('ldap') )
{
throw new \InvalidArgumentException( 'login_ldap_err' );
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack( 'login_ldap_err' ) );
}
try
@@ -190,7 +203,7 @@ class _LDAP extends \IPS\Login\Handler
}
catch ( LDAP\Exception $e )
{
throw new \InvalidArgumentException( $e->getMessage() ?: 'login_ldap_err_connect' );
throw new \InvalidArgumentException( $e->getMessage() ?: \IPS\Member::loggedIn()->language()->addToStack('login_ldap_err_connect' ) );
}
return TRUE;
@@ -203,7 +216,7 @@ class _LDAP extends \IPS\Login\Handler
*
* @param \IPS\Login $login The login object
* @param string $usernameOrEmail The username or email address provided by the user
* @param string $password The plaintext password provided by the user
* @param object $password The plaintext password provided by the user, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @return \IPS\Member
* @throws \IPS\Login\Exception
*/
@@ -213,16 +226,19 @@ class _LDAP extends \IPS\Login\Handler
{
$result = NULL;
/* Try email address */
if ( $this->authType() & \IPS\Login::AUTH_TYPE_EMAIL )
if( $usernameOrEmail )
{
$result = $this->_getUserWithFilter( $this->settings['email_field'] . '=' . ldap_escape( $usernameOrEmail, NULL, LDAP_ESCAPE_FILTER ) );
}
/* Try username */
if ( !$result and $this->authType() & \IPS\Login::AUTH_TYPE_USERNAME )
{
$result = $this->_getUserWithFilter( $this->_nameField() . '=' . ldap_escape( $usernameOrEmail . $this->settings['un_suffix'], NULL, LDAP_ESCAPE_FILTER ) );
/* Try email address */
if ( $this->authType() & \IPS\Login::AUTH_TYPE_EMAIL )
{
$result = $this->_getUserWithFilter( $this->settings['email_field'] . '=' . ldap_escape( $usernameOrEmail, NULL, LDAP_ESCAPE_FILTER ) );
}
/* Try username */
if ( !$result and $this->authType() & \IPS\Login::AUTH_TYPE_USERNAME )
{
$result = $this->_getUserWithFilter( $this->_nameField() . '=' . ldap_escape( $usernameOrEmail . $this->settings['un_suffix'], NULL, LDAP_ESCAPE_FILTER ) );
}
}
/* Don't have anything? */
@@ -313,12 +329,25 @@ class _LDAP extends \IPS\Login\Handler
{
if ( $exception->getCode() === \IPS\Login\Exception::MERGE_SOCIAL_ACCOUNT )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $this->id,
'token_member' => $exception->member->member_id,
'token_identifier' => $attrs[ $this->settings['uid_field'] ][0],
'token_linked' => 0,
) );
try
{
$identifier = \IPS\Db::i()->select( 'token_identifier', 'core_login_links', array( 'token_login_method=? AND token_member=?', $this->id, $exception->member->member_id ) )->first();
if( $identifier != $attrs[ $this->settings['uid_field'] ][0] )
{
$exception->setCode( \IPS\Login\Exception::LOCAL_ACCOUNT_ALREADY_MERGED );
throw $exception;
}
}
catch( \UnderflowException $e )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $this->id,
'token_member' => $exception->member->member_id,
'token_identifier' => $attrs[ $this->settings['uid_field'] ][0],
'token_linked' => 0,
) );
}
}
throw $exception;
@@ -336,7 +365,7 @@ class _LDAP extends \IPS\Login\Handler
* Authenticate
*
* @param \IPS\Member $member The member
* @param string $password The plaintext password provided by the user
* @param object $password The plaintext password provided by the user, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @return bool
*/
public function authenticatePasswordForMember( \IPS\Member $member, $password )
@@ -368,7 +397,7 @@ class _LDAP extends \IPS\Login\Handler
{
if ( !$this->_ldap )
{
$this->_ldap = ldap_connect( $this->settings['server_host'], ( isset( $this->settings['server_port'] ) and $this->settings['server_port'] ) ? intval( $this->settings['server_port'] ) : 389 );
$this->_ldap = ldap_connect( $this->settings['server_host'], ( isset( $this->settings['server_port'] ) and $this->settings['server_port'] ) ? \intval( $this->settings['server_port'] ) : 389 );
if ( !$this->_ldap )
{
throw new LDAP\Exception;
@@ -437,13 +466,13 @@ class _LDAP extends \IPS\Login\Handler
/**
* Password is valid
*
* @param resource $result The resource from LDAP
* @param string $providedPassword The provided password
* @param resource $result The resource from LDAP
* @param object $providedPassword The plaintext password provided by the user, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @return bool
*/
protected function _passwordIsValid( $result, $providedPassword )
{
return (bool) @ldap_bind( $this->_ldap(), ldap_get_dn( $this->_ldap(), $result ), ( $this->settings['pw_required'] ? $providedPassword : '' ) );
return (bool) @ldap_bind( $this->_ldap(), ldap_get_dn( $this->_ldap(), $result ), ( $this->settings['pw_required'] ? ( (string) $providedPassword ) : '' ) );
}
/* !Other Login Handler Methods */
@@ -462,6 +491,16 @@ class _LDAP extends \IPS\Login\Handler
return FALSE;
}
/**
* Can this handler sync passwords?
*
* @return bool
*/
public function canSyncPassword()
{
return (bool) ( isset( $this->settings['sync_password_changes'] ) AND $this->settings['sync_password_changes'] );
}
/**
* Email is in use?
* Used when registering or changing an email address to check the new one is available
@@ -564,7 +603,7 @@ class _LDAP extends \IPS\Login\Handler
* Change Password
*
* @param \IPS\Member $member The member
* @param string $newPassword New Password
* @param string $newPassword New Password, wrapped in an object that can be cast to a string so it doesn't show in any logs
* @return void
*/
public function changePassword( \IPS\Member $member, $newPassword )
@@ -727,4 +766,14 @@ class _LDAP extends \IPS\Login\Handler
return $return;
}
/**
* Has any sync options
*
* @return bool
*/
public function hasSyncOptions()
{
return TRUE;
}
}