| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- <?php
- /*
- * Copyright (C) 2015 Frederic France <frederic.france@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- /**
- * \file htdocs/includes/OAuth/Common/Storage/DoliStorage.php
- * \ingroup oauth
- * \brief Dolibarr token storage class
- */
- namespace OAuth\Common\Storage;
- use OAuth\Common\Token\TokenInterface;
- use OAuth\Common\Storage\Exception\TokenNotFoundException;
- use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
- use DoliDB;
- /**
- * Class to manage storage of OAUTH2 in Dolibarr
- */
- class DoliStorage implements TokenStorageInterface
- {
- /**
- * @var DoliDB Database handler
- */
- protected $db;
- /**
- * @var object|TokenInterface
- */
- protected $tokens;
- /**
- * @var string Error code (or message)
- */
- public $error;
- /**
- * @var string[] Several error codes (or messages)
- */
- public $errors = array();
- private $conf;
- private $key;
- //private $stateKey;
- private $keyforprovider;
- public $token;
- private $tenant;
- public $state;
- public $date_creation;
- public $date_modification;
- /**
- * @param DoliDB $db Database handler
- * @param Conf $conf Conf object
- * @param string $keyforprovider Key to manage several providers of the same type. For example 'abc' will be added to 'Google' to defined storage key.
- */
- public function __construct(DoliDB $db, $conf, $keyforprovider = '')
- {
- $this->db = $db;
- $this->conf = $conf;
- $this->keyforprovider = $keyforprovider;
- $this->token = '';
- $this->tokens = array();
- $this->states = array();
- //$this->key = $key;
- //$this->stateKey = $stateKey;
- }
- /**
- * {@inheritDoc}
- */
- public function retrieveAccessToken($service)
- {
- dol_syslog("retrieveAccessToken service=".$service);
- if ($this->hasAccessToken($service)) {
- return $this->tokens[$service];
- }
- throw new TokenNotFoundException('Token not found in db, are you sure you stored it?');
- }
- /**
- * {@inheritDoc}
- */
- public function storeAccessToken($service, TokenInterface $tokenobj)
- {
- global $conf;
- //var_dump("storeAccessToken");
- //var_dump($token);
- dol_syslog("storeAccessToken service=".$service);
- $servicepluskeyforprovider = $service;
- if (!empty($this->keyforprovider)) {
- // We clean the keyforprovider after the - to be sure it is not present
- $servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider);
- // Now we add the keyforprovider
- $servicepluskeyforprovider .= '-'.$this->keyforprovider;
- }
- include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
- $serializedToken = serialize($tokenobj);
- if (!is_array($this->tokens)) {
- $this->tokens = array();
- }
- $this->tokens[$service] = $tokenobj;
- $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."oauth_token";
- $sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'";
- $sql .= " AND entity IN (".getEntity('oauth_token').")";
- $resql = $this->db->query($sql);
- if (! $resql) {
- dol_print_error($this->db);
- }
- $obj = $this->db->fetch_array($resql);
- if ($obj) {
- // update
- $sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token";
- $sql.= " SET token = '".$this->db->escape(dolEncrypt($serializedToken))."'";
- $sql.= " WHERE rowid = ".((int) $obj['rowid']);
- $resql = $this->db->query($sql);
- if (!$resql) {
- dol_print_error($this->db);
- }
- } else {
- // save
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, token, entity, datec)";
- $sql .= " VALUES ('".$this->db->escape($servicepluskeyforprovider)."', '".$this->db->escape(dolEncrypt($serializedToken))."', ".((int) $conf->entity).", ";
- $sql .= " '".$this->db->idate(dol_now())."'";
- $sql .= ")";
- $resql = $this->db->query($sql);
- if (!$resql) {
- dol_print_error($this->db);
- }
- }
- //print $sql;
- // allow chaining
- return $this;
- }
- /**
- * Load token and other data from a $service
- * Note: Token load are cumulated into array ->tokens when other properties are erased by last loaded token.
- *
- * @return void
- */
- public function hasAccessToken($service)
- {
- // get from db
- dol_syslog("hasAccessToken service=".$service);
- $servicepluskeyforprovider = $service;
- if (!empty($this->keyforprovider)) {
- // We clean the keyforprovider after the - to be sure it is not present
- $servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider);
- // Now we add the keyforprovider
- $servicepluskeyforprovider .= '-'.$this->keyforprovider;
- }
- $sql = "SELECT token, datec, tms, state FROM ".MAIN_DB_PREFIX."oauth_token";
- $sql .= " WHERE service = '".$this->db->escape($servicepluskeyforprovider)."'";
- $sql .= " AND entity IN (".getEntity('oauth_token').")";
- $resql = $this->db->query($sql);
- if (! $resql) {
- dol_print_error($this->db);
- }
- $result = $this->db->fetch_array($resql);
- if ($result) {
- include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
- $tokenobj = unserialize(dolDecrypt($result['token']));
- $this->token = dolDecrypt($result['token']);
- $this->date_creation = $this->db->jdate($result['datec']);
- $this->date_modification = $this->db->jdate($result['tms']);
- $this->state = $result['state'];
- } else {
- $tokenobj = '';
- $this->token = '';
- $this->date_creation = null;
- $this->date_modification = null;
- $this->state = '';
- }
- $this->tokens[$service] = $tokenobj;
- return is_array($this->tokens)
- && isset($this->tokens[$service])
- && $this->tokens[$service] instanceof TokenInterface;
- }
- /**
- * {@inheritDoc}
- */
- public function clearToken($service)
- {
- dol_syslog("clearToken service=".$service);
- // TODO
- // get previously saved tokens
- //$tokens = $this->retrieveAccessToken($service);
- //if (is_array($tokens) && array_key_exists($service, $tokens)) {
- // unset($tokens[$service]);
- $sql = "DELETE FROM ".MAIN_DB_PREFIX."oauth_token";
- $sql .= " WHERE service = '".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."'";
- $sql .= " AND entity IN (".getEntity('oauth_token').")";
- $resql = $this->db->query($sql);
- //}
- // allow chaining
- return $this;
- }
- /**
- * {@inheritDoc}
- */
- public function clearAllTokens()
- {
- // TODO Remove token using a loop on each $service
- /*
- $servicepluskeyforprovider = $service;
- if (!empty($this->keyforprovider)) {
- // We clean the keyforprovider after the - to be sure it is not present
- $servicepluskeyforprovider = preg_replace('/\-'.preg_quote($this->keyforprovider, '/').'$/', '', $servicepluskeyforprovider);
- // Now we add the keyforprovider
- $servicepluskeyforprovider .= '-'.$this->keyforprovider;
- }
- */
- // allow chaining
- return $this;
- }
- /**
- * {@inheritDoc}
- */
- public function retrieveAuthorizationState($service)
- {
- if ($this->hasAuthorizationState($service)) {
- return $this->states[$service];
- }
- dol_syslog('State not found in db, are you sure you stored it?', LOG_WARNING);
- throw new AuthorizationStateNotFoundException('State not found in db, are you sure you stored it?');
- }
- /**
- * {@inheritDoc}
- */
- public function storeAuthorizationState($service, $state)
- {
- global $conf;
- dol_syslog("storeAuthorizationState service=".$service." state=".$state);
- if (!isset($this->states) || !is_array($this->states)) {
- $this->states = array();
- }
- //$states[$service] = $state;
- $this->states[$service] = $state;
- //$newstate = preg_replace('/\-.*$/', '', $state);
- $newstate = $state;
- $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."oauth_token";
- $sql .= " WHERE service = '".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."'";
- $sql .= " AND entity IN (".getEntity('oauth_token').")";
- $resql = $this->db->query($sql);
- if (! $resql) {
- dol_print_error($this->db);
- }
- $obj = $this->db->fetch_array($resql);
- if ($obj) {
- // update
- $sql = "UPDATE ".MAIN_DB_PREFIX."oauth_token";
- $sql.= " SET state = '".$this->db->escape($newstate)."'";
- $sql.= " WHERE rowid = ".((int) $obj['rowid']);
- $resql = $this->db->query($sql);
- } else {
- // insert (should not happen)
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."oauth_token (service, state, entity)";
- $sql.= " VALUES ('".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."', '".$this->db->escape($newstate)."', ".((int) $conf->entity).")";
- $resql = $this->db->query($sql);
- }
- // allow chaining
- return $this;
- }
- /**
- * {@inheritDoc}
- */
- public function hasAuthorizationState($service)
- {
- // get state from db
- dol_syslog("hasAuthorizationState service=".$service);
- $sql = "SELECT state FROM ".MAIN_DB_PREFIX."oauth_token";
- $sql .= " WHERE service = '".$this->db->escape($service.($this->keyforprovider?'-'.$this->keyforprovider:''))."'";
- $sql .= " AND entity IN (".getEntity('oauth_token').")";
- $resql = $this->db->query($sql);
- $result = $this->db->fetch_array($resql);
- $states = array();
- $states[$service] = $result['state'];
- $this->states[$service] = $states[$service];
- return is_array($states)
- && isset($states[$service])
- && null !== $states[$service];
- }
- /**
- * {@inheritDoc}
- */
- public function clearAuthorizationState($service)
- {
- // TODO
- // get previously saved tokens
- if (is_array($this->states) && array_key_exists($service, $this->states)) {
- unset($this->states[$service]);
- // Replace the stored tokens array
- //$this->conf->set($this->stateKey, $states);
- }
- // allow chaining
- return $this;
- }
- /**
- * {@inheritDoc}
- */
- public function clearAllAuthorizationStates()
- {
- // TODO
- // allow chaining
- return $this;
- }
- /**
- * Return the token
- *
- * @return string String for the tenant used to create the token
- */
- public function getTenant()
- {
- // Set/Reset tenant now so it will be defined for.
- // TODO We must store it into the table llx_oauth_token
- $this->tenant = getDolGlobalString('OAUTH_MICROSOFT'.($this->keyforprovider ? '-'.$this->keyforprovider : '').'_TENANT');
- return $this->tenant;
- }
- }
|