包含:登录失败锁定、90天密码有效期、30分钟会话超时、 强制改密、登录审计日志、屏幕水印、企业背景图、 备案信息固定底部、favicon、登录页JS修复等全部改动
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
namespace MRBS\Auth;
|
||||
|
||||
use MRBS\User;
|
||||
|
||||
/**
|
||||
* A class for authenticating against a Wix system. It requires code to be installed in
|
||||
* http-functions.js in the Wix backend. See wix/README for full details.
|
||||
*
|
||||
* It would be nice to be able to use Wix's OAuth2 server, but it seems to be limited to Wix apps.
|
||||
*
|
||||
* Another approach might be to use the Wix backend function getMember(), but this doesn't work inside
|
||||
* http_functions as the URL endpoint for http_functions is not associated with a user session.
|
||||
*/
|
||||
class AuthWix extends Auth
|
||||
{
|
||||
public function validateUser(
|
||||
#[\SensitiveParameter]
|
||||
?string $user,
|
||||
#[\SensitiveParameter]
|
||||
?string $pass)
|
||||
{
|
||||
if (!isset($user) || !isset($pass))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'email' => $user,
|
||||
'password' => $pass
|
||||
);
|
||||
|
||||
$result = $this->http_functions('validateMember', $params);
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
// curl_exec failure: we'll return false anyway
|
||||
return $result;
|
||||
}
|
||||
|
||||
return (json_decode($result)) ? $user : false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public function canValidateByEmail() : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public function canValidateByUsername() : bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected function getUserFresh(string $username) : ?User
|
||||
{
|
||||
global $auth;
|
||||
|
||||
$params = array('email' => $username);
|
||||
$result = $this->http_functions('getMemberByEmail', $params);
|
||||
|
||||
// The username doesn't exist - return NULL
|
||||
if (($result === false) || ($result === '') || ($result === json_encode(null)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = json_decode($result);
|
||||
|
||||
$user = new User($username);
|
||||
|
||||
// Set the email address
|
||||
$user->email = $result->member->loginEmail;
|
||||
|
||||
// Set the display name
|
||||
$property = $auth['wix']['display_name_property'] ?? 'name';
|
||||
if (isset($result->member->$property) && ($result->member->$property !== ''))
|
||||
{
|
||||
$user->display_name = $result->member->$property;
|
||||
}
|
||||
else
|
||||
{
|
||||
$user->display_name = $result->member->loginEmail;
|
||||
}
|
||||
|
||||
// Set the level
|
||||
// First get the default level. Any admins defined in the config
|
||||
// file override settings in the external database.
|
||||
$user->level = $this->getDefaultLevel($username);
|
||||
|
||||
// Then if they are not an admin get their admin status from Wix
|
||||
if (($user->level < 2) && isset($result->badges) && in_array($auth['wix']['admin_badge'], $result->badges))
|
||||
{
|
||||
$user->level = 2;
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
// Return an array of users, indexed by 'username' and 'display_name'
|
||||
public function getUsernames() : array
|
||||
{
|
||||
global $auth;
|
||||
|
||||
$params = array();
|
||||
|
||||
if (isset($auth['wix']['display_name_property']))
|
||||
{
|
||||
$params['display_name_property'] = $auth['wix']['display_name_property'];
|
||||
}
|
||||
|
||||
$result = $this->http_functions('getMemberNames', $params);
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$users = json_decode($result, true);
|
||||
|
||||
self::sortUsers($users);
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
|
||||
private function http_functions(string $function, array $params)
|
||||
{
|
||||
global $auth, $server;
|
||||
|
||||
// Add a trailing '/' if necessary
|
||||
if (!str_ends_with($auth['wix']['site_url'], '/'))
|
||||
{
|
||||
$auth['wix']['site_url'] .= '/';
|
||||
}
|
||||
|
||||
// Get a user agent to keep the other end happy
|
||||
if (isset($server['HTTP_USER_AGENT']) && ($server['HTTP_USER_AGENT'] !== ''))
|
||||
{
|
||||
$user_agent = $server['HTTP_USER_AGENT'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$user_agent = 'PHP';
|
||||
}
|
||||
|
||||
// Add in the API key
|
||||
$params['key'] = $auth['wix']['mrbs_api_key'];
|
||||
// And the API key secret name in Wix
|
||||
$params['secret_name'] = $auth['wix']['mrbs_api_key_secret_name'];
|
||||
|
||||
// And the limit, for internal use by the Wix backend code
|
||||
if (isset($auth['wix']['limit']))
|
||||
{
|
||||
$params['limit'] = $auth['wix']['limit'];
|
||||
}
|
||||
|
||||
$url = $auth['wix']['site_url'] . "_functions/$function";
|
||||
self::debug("URL=\"$url\"");
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
// Necessary to prevent "HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)" error;
|
||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
// Necessary to prevent "OpenSSL SSL_read: Connection reset by peer, errno 104" error;
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
|
||||
// Use compression if we can
|
||||
if (defined('CURLOPT_ENCODING'))
|
||||
{
|
||||
curl_setopt($ch, CURLOPT_ENCODING, '');
|
||||
}
|
||||
// Get some debug info in case there's an error
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$stream = fopen('php://temp', 'w+');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $stream);
|
||||
|
||||
$result = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
rewind($stream);
|
||||
$message = curl_error($ch);
|
||||
$message .= "\n\nCurl verbose log:\n\n" . stream_get_contents($stream);
|
||||
trigger_error($message, E_USER_WARNING);
|
||||
}
|
||||
elseif ($http_code != 200)
|
||||
{
|
||||
trigger_error("Curl received HTTP response code $http_code: $result", E_USER_WARNING);
|
||||
$result = false;
|
||||
}
|
||||
|
||||
fclose($stream);
|
||||
|
||||
// curl_close() doesn't do anything from PHP 8.0 onwards (because the curl
|
||||
// handle is an object and not a resource) and is deprecated from PHP 8.5.
|
||||
assert(version_compare(MRBS_MIN_PHP_VERSION, '8.0.0', '<'), "The code below is now redundant.");
|
||||
if (version_compare(PHP_VERSION, '8.0.0') < 0)
|
||||
{
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
private static function debug(string $message) : void
|
||||
{
|
||||
global $auth;
|
||||
|
||||
if ($auth['wix']['debug'])
|
||||
{
|
||||
self::logDebugMessage($message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user