| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- <?php
- trait AuthFunctions
- {
- public function testConnectionLdap()
- {
- if (!empty($this->config['authBaseDN']) && !empty($this->config['authBackendHost'])) {
- $ad = new \Adldap\Adldap();
- // Create a configuration array.
- $ldapServers = explode(',', $this->config['authBackendHost']);
- $i = 0;
- foreach ($ldapServers as $key => $value) {
- // Calculate parts
- $digest = parse_url(trim($value));
- $scheme = strtolower(($digest['scheme'] ?? 'ldap'));
- $host = ($digest['host'] ?? ($digest['path'] ?? ''));
- $port = ($digest['port'] ?? (strtolower($scheme) == 'ldap' ? 389 : 636));
- // Reassign
- $ldapHosts[] = $host;
- if ($i == 0) {
- $ldapPort = $port;
- }
- $i++;
- }
- $config = [
- // Mandatory Configuration Options
- 'hosts' => $ldapHosts,
- 'base_dn' => $this->config['authBaseDN'],
- 'username' => (empty($this->config['ldapBindUsername'])) ? null : $this->config['ldapBindUsername'],
- 'password' => (empty($this->config['ldapBindPassword'])) ? null : $this->decrypt($this->config['ldapBindPassword']),
- // Optional Configuration Options
- 'schema' => (($this->config['ldapType'] == '1') ? Adldap\Schemas\ActiveDirectory::class : (($this->config['ldapType'] == '2') ? Adldap\Schemas\OpenLDAP::class : Adldap\Schemas\FreeIPA::class)),
- 'account_prefix' => '',
- 'account_suffix' => '',
- 'port' => $ldapPort,
- 'follow_referrals' => false,
- 'use_ssl' => $this->config['ldapSSL'],
- 'use_tls' => $this->config['ldapTLS'],
- 'version' => 3,
- 'timeout' => 5,
- // Custom LDAP Options
- 'custom_options' => [
- // See: http://php.net/ldap_set_option
- //LDAP_OPT_X_TLS_REQUIRE_CERT => LDAP_OPT_X_TLS_HARD
- ]
- ];
- // Add a connection provider to Adldap.
- $ad->addProvider($config);
- try {
- // If a successful connection is made to your server, the provider will be returned.
- $provider = $ad->connect();
- } catch (\Adldap\Auth\BindException $e) {
- $detailedError = $e->getDetailedError();
- $this->writeLog('error', 'LDAP Function - Error: ' . $detailedError->getErrorMessage(), 'SYSTEM');
- $this->setAPIResponse('error', $detailedError->getErrorMessage(), 409);
- return $detailedError->getErrorMessage();
- // There was an issue binding / connecting to the server.
- }
- if ($provider) {
- $this->setAPIResponse('success', 'LDAP connection successful', 200);
- return true;
- } else {
- $this->setAPIResponse('error', 'Could not connect', 500);
- return false;
- }
- return ($provider) ? true : false;
- } else {
- $this->setAPIResponse('error', 'authBaseDN and/or BackendHost not supplied', 422);
- return false;
- }
- }
-
- public function testConnectionLdapLogin($array)
- {
- $username = $array['username'] ?? null;
- $password = $array['password'] ?? null;
- if (empty($username) || empty($password)) {
- $this->setAPIResponse('error', 'Username and/or Password not supplied', 422);
- return false;
- }
- if (!empty($this->config['authBaseDN']) && !empty($this->config['authBackendHost'])) {
- $ad = new \Adldap\Adldap();
- // Create a configuration array.
- $ldapServers = explode(',', $this->config['authBackendHost']);
- $i = 0;
- foreach ($ldapServers as $key => $value) {
- // Calculate parts
- $digest = parse_url(trim($value));
- $scheme = strtolower(($digest['scheme'] ?? 'ldap'));
- $host = ($digest['host'] ?? ($digest['path'] ?? ''));
- $port = ($digest['port'] ?? (strtolower($scheme) == 'ldap' ? 389 : 636));
- // Reassign
- $ldapHosts[] = $host;
- $ldapServersNew[$key] = $scheme . '://' . $host . ':' . $port; // May use this later
- if ($i == 0) {
- $ldapPort = $port;
- }
- $i++;
- }
- $config = [
- // Mandatory Configuration Options
- 'hosts' => $ldapHosts,
- 'base_dn' => $this->config['authBaseDN'],
- 'username' => (empty($this->config['ldapBindUsername'])) ? null : $this->config['ldapBindUsername'],
- 'password' => (empty($this->config['ldapBindPassword'])) ? null : $this->decrypt($this->config['ldapBindPassword']),
- // Optional Configuration Options
- 'schema' => (($this->config['ldapType'] == '1') ? Adldap\Schemas\ActiveDirectory::class : (($this->config['ldapType'] == '2') ? Adldap\Schemas\OpenLDAP::class : Adldap\Schemas\FreeIPA::class)),
- 'account_prefix' => (empty($this->config['authBackendHostPrefix'])) ? null : $this->config['authBackendHostPrefix'],
- 'account_suffix' => (empty($this->config['authBackendHostSuffix'])) ? null : $this->config['authBackendHostSuffix'],
- 'port' => $ldapPort,
- 'follow_referrals' => false,
- 'use_ssl' => $this->config['ldapSSL'],
- 'use_tls' => $this->config['ldapTLS'],
- 'version' => 3,
- 'timeout' => 5,
- // Custom LDAP Options
- 'custom_options' => [
- // See: http://php.net/ldap_set_option
- //LDAP_OPT_X_TLS_REQUIRE_CERT => LDAP_OPT_X_TLS_HARD
- ]
- ];
- // Add a connection provider to Adldap.
- $ad->addProvider($config);
- try {
- // If a successful connection is made to your server, the provider will be returned.
- $provider = $ad->connect();
- //prettyPrint($provider);
- if ($provider->auth()->attempt($username, $password, true)) {
- // Passed.
- $user = $provider->search()->find($username);
- //return $user->getFirstAttribute('cn');
- //return $user->getGroups(['cn']);
- //return $user;
- //return $user->getUserPrincipalName();
- //return $user->getGroups(['cn']);
- $this->setResponse(200, 'LDAP connection successful');
- return true;
- } else {
- // Failed.
- $this->setResponse(401, 'Username/Password Failed to authenticate');
- return false;
- }
- } catch (\Adldap\Auth\BindException $e) {
- $detailedError = $e->getDetailedError();
- $this->writeLog('error', 'LDAP Function - Error: ' . $detailedError->getErrorMessage(), $username);
- $this->setAPIResponse('error', $detailedError->getErrorMessage(), 500);
- return $detailedError->getErrorMessage();
- // There was an issue binding / connecting to the server.
- } catch (Adldap\Auth\UsernameRequiredException $e) {
- $detailedError = $e->getDetailedError();
- $this->writeLog('error', 'LDAP Function - Error: ' . $detailedError->getErrorMessage(), $username);
- $this->setAPIResponse('error', $detailedError->getErrorMessage(), 422);
- return $detailedError->getErrorMessage();
- // The user didn't supply a username.
- } catch (Adldap\Auth\PasswordRequiredException $e) {
- $detailedError = $e->getDetailedError();
- $this->writeLog('error', 'LDAP Function - Error: ' . $detailedError->getErrorMessage(), $username);
- $this->setAPIResponse('error', $detailedError->getErrorMessage(), 422);
- return $detailedError->getErrorMessage();
- // The user didn't supply a password.
- }
- } else {
- $this->setAPIResponse('error', 'authBaseDN and/or BackendHost not supplied', 422);
- return false;
- }
- }
-
- public function checkPlexToken($token = '')
- {
- try {
- if (($token !== '')) {
- $url = 'https://plex.tv/users/account.json';
- $headers = array(
- 'X-Plex-Token' => $token,
- 'Content-Type' => 'application/json',
- 'Accept' => 'application/json'
- );
- $response = Requests::get($url, $headers);
- if ($response->success) {
- return json_decode($response->body, true);
- }
- } else {
- return false;
- }
-
- } catch (Requests_Exception $e) {
- $this->writeLog('success', 'Plex Token Check Function - Error: ' . $e->getMessage(), 'SYSTEM');
- }
- return false;
- }
-
- public function checkPlexUser($username)
- {
- try {
- if (!empty($this->config['plexToken'])) {
- $url = 'https://plex.tv/api/users';
- $headers = array(
- 'X-Plex-Token' => $this->config['plexToken'],
- );
- $response = Requests::get($url, $headers);
- if ($response->success) {
- libxml_use_internal_errors(true);
- $userXML = simplexml_load_string($response->body);
- if (is_array($userXML) || is_object($userXML)) {
- $usernameLower = strtolower($username);
- foreach ($userXML as $child) {
- if (isset($child['username']) && strtolower($child['username']) == $usernameLower || isset($child['email']) && strtolower($child['email']) == $usernameLower) {
- $this->writeLog('success', 'Plex User Check - Found User on Friends List', $username);
- $machineMatches = false;
- if ($this->config['plexStrictFriends']) {
- foreach ($child->Server as $server) {
- if ((string)$server['machineIdentifier'] == $this->config['plexID']) {
- $machineMatches = true;
- }
- }
- } else {
- $machineMatches = true;
- }
- if ($machineMatches) {
- $this->writeLog('success', 'Plex User Check - User Approved for Login', $username);
- return true;
- } else {
- $this->writeLog('error', 'Plex User Check - User not Approved User', $username);
- }
- }
- }
- }
- }
- }
- return false;
- } catch (Requests_Exception $e) {
- $this->writeLog('error', 'Plex User Check Function - Error: ' . $e->getMessage(), $username);
- }
- return false;
- }
-
- public function plugin_auth_plex($username, $password)
- {
- try {
- $usernameLower = strtolower($username);
- //Login User
- $url = 'https://plex.tv/users/sign_in.json';
- $headers = array(
- 'Accept' => 'application/json',
- 'Content-Type' => 'application/x-www-form-urlencoded',
- 'X-Plex-Product' => 'Organizr',
- 'X-Plex-Version' => '2.0',
- 'X-Plex-Client-Identifier' => $this->config['uuid'],
- );
- $data = array(
- 'user[login]' => $username,
- 'user[password]' => $password,
- );
- $options = array('timeout' => 30);
- $response = Requests::post($url, $headers, $data, $options);
- if ($response->success) {
- $json = json_decode($response->body, true);
- if ((is_array($json) && isset($json['user']) && isset($json['user']['username'])) && strtolower($json['user']['username']) == $usernameLower || strtolower($json['user']['email']) == $usernameLower) {
- if ((!empty($this->config['plexAdmin']) && (strtolower($this->config['plexAdmin']) == strtolower($json['user']['username']) || strtolower($this->config['plexAdmin']) == strtolower($json['user']['email']))) || $this->checkPlexUser($json['user']['username'])) {
- return array(
- 'username' => $json['user']['username'],
- 'email' => $json['user']['email'],
- 'image' => $json['user']['thumb'],
- 'token' => $json['user']['authToken']
- );
- }
- }
- }
- return false;
- } catch (Requests_Exception $e) {
- $this->writeLog('success', 'Plex Auth Function - Error: ' . $e->getMessage(), $username);
- }
- return false;
- }
-
- // Pass credentials to LDAP backend
- public function plugin_auth_ldap($username, $password)
- {
- if (!empty($this->config['authBaseDN']) && !empty($this->config['authBackendHost'])) {
- $ad = new \Adldap\Adldap();
- // Create a configuration array.
- $ldapServers = explode(',', $this->config['authBackendHost']);
- $i = 0;
- foreach ($ldapServers as $key => $value) {
- // Calculate parts
- $digest = parse_url(trim($value));
- $scheme = strtolower((isset($digest['scheme']) ? $digest['scheme'] : 'ldap'));
- $host = (isset($digest['host']) ? $digest['host'] : (isset($digest['path']) ? $digest['path'] : ''));
- $port = (isset($digest['port']) ? $digest['port'] : (strtolower($scheme) == 'ldap' ? 389 : 636));
- // Reassign
- $ldapHosts[] = $host;
- $ldapServersNew[$key] = $scheme . '://' . $host . ':' . $port; // May use this later
- if ($i == 0) {
- $ldapPort = $port;
- }
- $i++;
- }
- $config = [
- // Mandatory Configuration Options
- 'hosts' => $ldapHosts,
- 'base_dn' => $this->config['authBaseDN'],
- 'username' => (empty($this->config['ldapBindUsername'])) ? null : $this->config['ldapBindUsername'],
- 'password' => (empty($this->config['ldapBindPassword'])) ? null : $this->decrypt($this->config['ldapBindPassword']),
- // Optional Configuration Options
- 'schema' => (($this->config['ldapType'] == '1') ? Adldap\Schemas\ActiveDirectory::class : (($this->config['ldapType'] == '2') ? Adldap\Schemas\OpenLDAP::class : Adldap\Schemas\FreeIPA::class)),
- 'account_prefix' => (empty($this->config['authBackendHostPrefix'])) ? null : $this->config['authBackendHostPrefix'],
- 'account_suffix' => (empty($this->config['authBackendHostSuffix'])) ? null : $this->config['authBackendHostSuffix'],
- 'port' => $ldapPort,
- 'follow_referrals' => false,
- 'use_ssl' => $this->config['ldapSSL'],
- 'use_tls' => $this->config['ldapTLS'],
- 'version' => 3,
- 'timeout' => 5,
- // Custom LDAP Options
- 'custom_options' => [
- // See: http://php.net/ldap_set_option
- //LDAP_OPT_X_TLS_REQUIRE_CERT => LDAP_OPT_X_TLS_HARD
- ]
- ];
- // Add a connection provider to Adldap.
- $ad->addProvider($config);
- try {
- // If a successful connection is made to your server, the provider will be returned.
- $provider = $ad->connect();
- //prettyPrint($provider);
- if ($provider->auth()->attempt($username, $password)) {
- try {
- // Try and get email from LDAP server
- $accountDN = ((empty($this->config['authBackendHostPrefix'])) ? null : $this->config['authBackendHostPrefix']) . $username . ((empty($this->config['authBackendHostSuffix'])) ? null : $this->config['authBackendHostSuffix']);
- $record = $provider->search()->findByDnOrFail($accountDN);
- $email = $record->getFirstAttribute('mail');
- } catch (Adldap\Models\ModelNotFoundException $e) {
- // Record wasn't found!
- $email = null;
- }
- // Passed.
- return array(
- 'email' => $email
- );
- } else {
- // Failed.
- return false;
- }
- } catch (\Adldap\Auth\BindException $e) {
- $this->writeLog('error', 'LDAP Function - Error: ' . $e->getMessage(), $username);
- // There was an issue binding / connecting to the server.
- } catch (Adldap\Auth\UsernameRequiredException $e) {
- $this->writeLog('error', 'LDAP Function - Error: ' . $e->getMessage(), $username);
- // The user didn't supply a username.
- } catch (Adldap\Auth\PasswordRequiredException $e) {
- $this->writeLog('error', 'LDAP Function - Error: ' . $e->getMessage(), $username);
- // The user didn't supply a password.
- }
- }
- return false;
- }
-
- // Ldap Auth Missing Dependency
- public function plugin_auth_ldap_disabled()
- {
- return 'LDAP - Disabled (Dependency: php-ldap missing!)';
- }
-
- // Pass credentials to FTP backend
- public function plugin_auth_ftp($username, $password)
- {
- // Calculate parts
- $digest = parse_url($this->config['authBackendHost']);
- $scheme = strtolower((isset($digest['scheme']) ? $digest['scheme'] : (function_exists('ftp_ssl_connect') ? 'ftps' : 'ftp')));
- $host = (isset($digest['host']) ? $digest['host'] : (isset($digest['path']) ? $digest['path'] : ''));
- $port = (isset($digest['port']) ? $digest['port'] : 21);
- // Determine Connection Type
- if ($scheme == 'ftps') {
- $conn_id = ftp_ssl_connect($host, $port, 20);
- } elseif ($scheme == 'ftp') {
- $conn_id = ftp_connect($host, $port, 20);
- } else {
- return false;
- }
- // Check if valid FTP connection
- if ($conn_id) {
- // Attempt login
- @$login_result = ftp_login($conn_id, $username, $password);
- ftp_close($conn_id);
- // Return Result
- if ($login_result) {
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-
- // Pass credentials to Emby Backend
- public function plugin_auth_emby_local($username, $password)
- {
- try {
- $url = $this->qualifyURL($this->config['embyURL']) . '/Users/AuthenticateByName';
- $headers = array(
- 'Authorization' => 'Emby UserId="e8837bc1-ad67-520e-8cd2-f629e3155721", Client="None", Device="Organizr", DeviceId="xxx", Version="1.0.0.0"',
- 'Content-Type' => 'application/json',
- );
- $data = array(
- 'Username' => $username,
- 'pw' => $password,
- 'Password' => sha1($password),
- 'PasswordMd5' => md5($password),
- );
- $response = Requests::post($url, $headers, json_encode($data));
- if ($response->success) {
- $json = json_decode($response->body, true);
- if (is_array($json) && isset($json['SessionInfo']) && isset($json['User']) && $json['User']['HasPassword'] == true) {
- // Login Success - Now Logout Emby Session As We No Longer Need It
- $headers = array(
- 'X-Emby-Token' => $json['AccessToken'],
- 'X-Mediabrowser-Token' => $json['AccessToken'],
- );
- $response = Requests::post($this->qualifyURL($this->config['embyURL']) . '/Sessions/Logout', $headers, array());
- if ($response->success) {
- return true;
- }
- }
- }
- return false;
- } catch (Requests_Exception $e) {
- $this->writeLog('error', 'Emby Local Auth Function - Error: ' . $e->getMessage(), $username);
- }
- return false;
- }
-
- // Pass credentials to JellyFin Backend
- public function plugin_auth_jellyfin($username, $password)
- {
- try {
- $url = $this->qualifyURL($this->config['jellyfinURL']) . '/Users/authenticatebyname';
- $headers = array(
- 'X-Emby-Authorization' => 'MediaBrowser Client="Organizr Auth", Device="Organizr", DeviceId="orgv2", Version="2.0"',
- 'Content-Type' => 'application/json',
- );
- $data = array(
- 'Username' => $username,
- 'Pw' => $password
- );
- $response = Requests::post($url, $headers, json_encode($data));
- if ($response->success) {
- $json = json_decode($response->body, true);
- if (is_array($json) && isset($json['SessionInfo']) && isset($json['User']) && $json['User']['HasPassword'] == true) {
- $this->writeLog('success', 'JellyFin Auth Function - Found User and Logged In', $username);
- // Login Success - Now Logout JellyFin Session As We No Longer Need It
- $headers = array(
- 'X-Emby-Authorization' => 'MediaBrowser Client="Organizr Auth", Device="Organizr", DeviceId="orgv2", Version="2.0", Token="' . $json['AccessToken'] . '"',
- 'Content-Type' => 'application/json',
- );
- $response = Requests::post($this->qualifyURL($this->config['jellyfinURL']) . '/Sessions/Logout', $headers, array());
- if ($response->success) {
- return true;
- }
- }
- }
- return false;
- } catch (Requests_Exception $e) {
- $this->writeLog('error', 'JellyFin Auth Function - Error: ' . $e->getMessage(), $username);
- }
- return false;
- }
-
- // Authenticate against emby connect
- public function plugin_auth_emby_connect($username, $password)
- {
- // Emby disabled EmbyConnect on their API
- // https://github.com/MediaBrowser/Emby/issues/3553
- //return plugin_auth_emby_local($username, $password);
- try {
- // Get A User
- $connectUserName = '';
- $url = $this->qualifyURL($this->config['embyURL']) . '/Users?api_key=' . $this->config['embyToken'];
- $response = Requests::get($url);
- if ($response->success) {
- $json = json_decode($response->body, true);
- if (is_array($json)) {
- foreach ($json as $key => $value) { // Scan for this user
- if (isset($value['ConnectUserName']) && isset($value['ConnectLinkType'])) { // Qualify as connect account
- if (strtolower($value['ConnectUserName']) == $username || strtolower($value['Name']) == $username) {
- $connectUserName = $value['ConnectUserName'];
- $this->writeLog('success', 'Emby Connect Auth Function - Found User', $username);
- break;
- }
- }
- }
- if ($connectUserName) {
- $this->writeLog('success', 'Emby Connect Auth Function - Attempting to Login with Emby ID: ' . $connectUserName, $username);
- $connectURL = 'https://connect.emby.media/service/user/authenticate';
- $headers = array(
- 'Accept' => 'application/json',
- 'X-Application' => 'Organizr/2.0'
- );
- $data = array(
- 'nameOrEmail' => $username,
- 'rawpw' => $password,
- );
- $response = Requests::post($connectURL, $headers, $data);
- if ($response->success) {
- $json = json_decode($response->body, true);
- if (is_array($json) && isset($json['AccessToken']) && isset($json['User']) && $json['User']['Name'] == $connectUserName) {
- return array(
- 'email' => $json['User']['Email'],
- //'image' => $json['User']['ImageUrl'],
- );
- } else {
- $this->writeLog('error', 'Emby Connect Auth Function - Bad Response', $username);
- }
- } else {
- $this->writeLog('error', 'Emby Connect Auth Function - 401 From Emby Connect', $username);
- }
- }
- }
- }
- return false;
- } catch (Requests_Exception $e) {
- $this->writeLog('error', 'Emby Connect Auth Function - Error: ' . $e->getMessage(), $username);
- return false;
- }
- }
-
- // Authenticate Against Emby Local (first) and Emby Connect
- public function plugin_auth_emby_all($username, $password)
- {
- // Emby disabled EmbyConnect on their API
- // https://github.com/MediaBrowser/Emby/issues/3553
- $localResult = $this->plugin_auth_emby_local($username, $password);
- //return $localResult;
- if ($localResult) {
- return $localResult;
- } else {
- return $this->plugin_auth_emby_connect($username, $password);
- }
- }
-
- }
|