config) && $this->config['debug'] === true) { $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); if ($bt[0]['file'] != $lastfile) { file_put_contents('/var/alchemy/Phraseanet/logs/openid.log', sprintf("FILE %s \n", ($lastfile = $bt[0]['file'])), FILE_APPEND); } $s = sprintf("LINE (%d) : %s\n", $bt[0]['line'], $s); file_put_contents('/var/alchemy/Phraseanet/logs/openid.log', $s, FILE_APPEND); } } public function __construct(UrlGenerator $urlGenerator, SessionInterface $session, array $config, Guzzle $client) { parent::__construct($urlGenerator, $session); $this->config = $config; if(!array_key_exists('model-gpfx', $this->config)) { $this->config['model-gpfx'] = '_G_'; } if(!array_key_exists('model-upfx', $this->config)) { $this->config['model-upfx'] = '_U_'; } if(!array_key_exists('metamodel', $this->config)) { $this->config['metamodel'] = '_metamodel'; } if(!array_key_exists('auto-logout', $this->config)) { $this->config['auto-logout'] = false; } if(!array_key_exists('auto-connect-idp-name', $this->config)) { $this->config['auto-connect-idp-name'] = null; } $this->client = $client; $this->iconUri = array_key_exists('icon-uri', $config) ? $config['icon-uri'] : null; // if not set, will fallback on default icon } /** * {@inheritdoc} */ public static function create(UrlGenerator $generator, SessionInterface $session, array $options): AbstractProvider { foreach (['client-id', 'client-secret', 'base-url', 'realm-name'] as $parm) { if (!isset($options[$parm]) || (trim($options[$parm]) == '')) { throw new InvalidArgumentException(sprintf('Missing Phraseanet "%s" parameter in conf/authentification/providers', $parm)); } } $guzzle = new Guzzle(); $guzzle->setSslVerification(false, false, 0); return new self($generator, $session, $options, $guzzle); } /** * {@inheritdoc} */ public function getName(): string { return 'openid'; } /** * @param ClientInterface $client * * @return self */ public function setGuzzleClient(ClientInterface $client): self { $this->client = $client; return $this; } /** * @return ClientInterface */ public function getGuzzleClient() { return $this->client; } /** * {@inheritdoc} */ public function authenticate(array $params = array()): RedirectResponse { $this->debug(); $this->session->invalidate(0); /* * for oauth2 the callback url(s) MUST be fully static. One CAN register multiple possible urls, like * - one for phraseanet home : already static * - one for phraseanet oauth api * - ... ? * api client may want to include static/variable params to be used for final redirect (eg. parade), * we pass those in session * lib/Alchemy/Phrasea/Controller/Api/OAuth2Controller::authorizeCallbackAction(...) will restore params */ $this->session->set($this->getId() . ".parms", array_merge(['providerId' => $this->getId()], $params)); $this->debug(sprintf("authenticate params saved : session[%s] = %s", $this->getId() . ".parms", var_export($params, true) )); $params = ['providerId' => $this->getId()]; // the only required parm (constant) $this->debug(sprintf("redirect_uri params (cleaned) = %s", var_export($params, true))); $redirect_uri = $this->generator->generate( 'login_authentication_provider_callback', $params, UrlGeneratorInterface::ABSOLUTE_URL ); $this->debug(sprintf("redirect_uri = %s", $redirect_uri)); $state = $this->createState(); $this->session->set($this->getId() . '.provider.state', $state); $parms = [ 'client_id' => $this->config['client-id'], 'state' => $state, 'scope' => 'openid', 'redirect_uri' => $redirect_uri, 'response_type' => "code" ]; if($this->config['auto-connect-idp-name']) { $url = sprintf("%s/realms/%s/protocol/openid-connect/auth?kc_idp_hint=%s&%s", $this->config['base-url'], urlencode($this->config['realm-name']), urlencode($this->config['auto-connect-idp-name']), http_build_query($parms, '', '&') ); } else { $url = sprintf("%s/realms/%s/protocol/openid-connect/auth?%s", $this->config['base-url'], urlencode($this->config['realm-name']), http_build_query($parms, '', '&') ); } $this->debug(sprintf("go to url = %s", $url)); return new RedirectResponse($url); } /** * {@inheritdoc} */ public function logout() { $this->debug("logout ?"); if($this->config['auto-logout']) { // too bad: getting the logout page is not enough... // $url = "/logout"; // $guzzleRequest = $this->client->get($url); // $response = $guzzleRequest->send(); // $this->debug($response->getBody()); // return null; // ... we really need to redirect to it, which will prevent phr to redirect to his home $url = sprintf("%s/realms/%s/protocol/openid-connect/logout", $this->config['base-url'], urlencode($this->config['realm-name']) ); return new RedirectResponse($url); } return null; } public function logoutAndRedirect($redirect_uri) { $this->debug("logoutAndRedirect ?"); if($this->config['auto-logout']) { $url = sprintf("%s/realms/%s/protocol/openid-connect/logout?post_logout_redirect_uri=%s&id_token_hint=%s", $this->config['base-url'], urlencode($this->config['realm-name']), urlencode($redirect_uri), $this->session->get($this->getId() . '.provider.id_token') ); return new RedirectResponse($url); } return null; } /** * {@inheritdoc} */ public function onCallback(Request $request) { $this->debug(); if (!$this->session->has($this->getId() . '.provider.state')) { throw new NotAuthenticatedException('No state value in session ; CSRF try ?'); } $this->debug(); if ($request->query->get('state') !== $this->session->remove($this->getId() . '.provider.state')) { throw new NotAuthenticatedException('Invalid state value ; CSRF try ?'); } $this->debug(); try { $url = sprintf("%s/realms/%s/protocol/openid-connect/token", $this->config['base-url'], urlencode($this->config['realm-name']) ); $guzzleRequest = $this->client->post($url); $guzzleRequest->addPostFields([ 'grant_type' => "authorization_code", 'code' => $request->query->get('code'), 'redirect_uri' => $this->generator->generate( 'login_authentication_provider_callback', ['providerId' => $this->getId()], UrlGeneratorInterface::ABSOLUTE_URL ), 'client_id' => $this->config['client-id'], 'client_secret' => $this->config['client-secret'], ]); $guzzleRequest->setHeader('Accept', 'application/json'); $this->debug(); $response = $guzzleRequest->send(); $this->debug(); } catch (GuzzleException $e) { $this->debug($e->getMessage()); throw new NotAuthenticatedException('Guzzle error while authentication', $e->getCode(), $e); } if (200 !== $response->getStatusCode()) { $this->debug(); throw new NotAuthenticatedException('Error while getting access_token'); } $this->debug(); $data = @json_decode($response->getBody(true), true); $this->debug(); if (JSON_ERROR_NONE !== json_last_error()) { $this->debug(); throw new NotAuthenticatedException('Error while decoding token response, unable to parse JSON.'); } $this->debug(var_export($data, true)); $this->session->remove($this->getId() . '.provider.state'); $this->session->set($this->getId() . '.provider.access_token', $data['access_token']); // id_token_hint used when logout $this->session->set($this->getId() . '.provider.id_token', $data['id_token']); $this->session->set('provider.token_info', $data); try { $this->debug(); $uri = sprintf("%s/realms/%s/protocol/openid-connect/userinfo", $this->config['base-url'], urlencode($this->config['realm-name']) ); $request = $this->client->get($uri); $request->setHeader('Authorization', 'Bearer '. $data['access_token']); $this->debug(); $response = $request->send(); $this->debug(); } catch (GuzzleException $e) { $this->debug($e->getMessage()); throw new NotAuthenticatedException('Guzzle error while authentication', $e->getCode(), $e); } if (200 !== $response->getStatusCode()) { $this->debug(); throw new NotAuthenticatedException('Error while retrieving user info, invalid status code.'); } $this->debug(); $data = @json_decode($response->getBody(true), true); $this->debug(var_export($data, true)); if (JSON_ERROR_NONE !== json_last_error()) { $this->debug(); throw new NotAuthenticatedException('Error while retrieving user info, unable to parse JSON.'); } $this->debug(); $usegroups = isset($this->config['usegroups']) ? $this->config['usegroups'] : false; $idKey = isset($this->config['fieldmap']['id']) ? $this->config['fieldmap']['id'] : 'sub'; $loginKey = isset($this->config['fieldmap']['login']) ? $this->config['fieldmap']['login'] : 'email'; $firstnameKey = isset($this->config['fieldmap']['firstname']) ? $this->config['fieldmap']['firstname'] : 'given_name'; $lastnameKey = isset($this->config['fieldmap']['lastname']) ? $this->config['fieldmap']['lastname'] : 'family_name'; $emailKey = isset($this->config['fieldmap']['email']) ? $this->config['fieldmap']['email'] : 'email'; $groupsKey = isset($this->config['fieldmap']['groups']) ? $this->config['fieldmap']['groups'] : 'groups'; $distantUserId = $data['sub']; if (!\Swift_Validate::email($data[$loginKey]) && isset($data['email'])) { $loginKey = 'email';// login to be an email } $userUA = $this->CreateUser([ 'id' => $data[$idKey], 'login' => $userName = $data[$loginKey], 'firstname' => isset($data[$firstnameKey]) ? $data[$firstnameKey] : '', 'lastname' => isset($data[$lastnameKey]) ? $data[$lastnameKey] : '' , 'email' => isset($data[$emailKey]) ? $data[$emailKey] : '', '_groups' => isset($data[$groupsKey]) && $usegroups ? $this->filterGroups($data[$groupsKey]) : '' ]); $userAuthProviderRepository = $this->getUsrAuthProviderRepository(); $userAuthProvider = $userAuthProviderRepository ->findWithProviderAndId($this->getId(), $distantUserId); if (!$userAuthProvider) { $manager = $this->getEntityManager(); $usrAuthProvider = new UsrAuthProvider(); $usrAuthProvider->setDistantId($distantUserId); $usrAuthProvider->setProvider($this->getId()); $usrAuthProvider->setUser($userUA); try { $manager->persist($usrAuthProvider); $manager->flush(); } catch (\Exception $e) { // no-op $this->debug(); } } $this->session->set($this->getId() . ".provider.id", $distantUserId); $this->session->set($this->getId() . ".provider.username", $userName); $this->debug(sprintf("session->set('%s', '%s')", $this->getId() . ".provider.id", $distantUserId)); $this->debug(sprintf("session->set('%s', '%s')", $this->getId() . ".provider.username", $userName)); } /** * {@inheritdoc} */ public function getToken(): Token { $this->debug(); $distantUserId = $this->session->get($this->getId() . '.provider.id'); $this->debug(sprintf("session->get('%s') ==> '%s')", $this->getId() . ".provider.id", $distantUserId)); if ('' === trim($distantUserId)) { $this->debug(); throw new NotAuthenticatedException($this->getId() . ' has not authenticated'); } $this->debug(); $token = new Token($this, $distantUserId); $this->debug(); return $token; } /** * {@inheritdoc} */ public function getIdentity(): Identity { $this->debug(); $identity = new Identity(); try { $uri = sprintf("%s/realms/%s/protocol/openid-connect/userinfo", $this->config['base-url'], urlencode($this->config['realm-name']) ); $request = $this->client->get($uri); $request->setHeader('Authorization', 'Bearer '. $this->session->get($this->getId() . '.provider.access_token')); $response = $request->send(); } catch (GuzzleException $e) { $this->debug(); throw new NotAuthenticatedException('Error while retrieving user info', $e->getCode(), $e); } if (200 !== $response->getStatusCode()) { $this->debug(); throw new NotAuthenticatedException('Error while retrieving user info'); } $data = @json_decode($response->getBody(true), true); if (JSON_ERROR_NONE !== json_last_error()) { $this->debug(); throw new NotAuthenticatedException('Error while parsing json'); } $this->debug(); $identity->set(Identity::PROPERTY_EMAIL, isset($data['email']) ? $data['email'] : ''); $identity->set(Identity::PROPERTY_ID, $data['sub']); $identity->set(Identity::PROPERTY_USERNAME, $data['preferred_username']); $this->debug(); return $identity; } /** * @param array $data * @return User|null * @throws Exception */ private function CreateUser(Array $data) { $userManipulator = $this->getUserManipulator(); $userRepository = $this->getUserRepository(); $ACLProvider = $this->getACLProvider(); $ret = null; $login = trim($data['login']); $this->debug(sprintf("login=%s \n", var_export($login, true))); if ($login == "") { $this->debug("login is empty, user not created \n"); } /** @var User $userUA */ $userUA = $userRepository->findByLogin($login); if (!$userUA) { // need to create the user $this->debug(sprintf("creating user \"%s\" \n", $login)); $tmp_email = str_replace(['.', '@'], ['_', '_'], $login) . "@nomail.eu"; $userUA = $userManipulator->createUser($login, 'user_tmp_pwd', $tmp_email, false); if ($userUA) { $this->debug(sprintf("found user \"%s\" with id=%s \n", $login, $userUA->getId())); // if the id provider does NOT return groups, the new user will get "birth" privileges if (!is_array($data['_groups']) && array_key_exists('birth-group', $this->config) && trim($this->config['birth-group']) !== '') { $data['_groups'] = [trim($this->config['birth-group'])]; } } else { $this->debug(sprintf("failed to create user \"%s\" \n", $login)); } } else { // the user already exists $this->debug(sprintf("found user \"%s\" with id=%s \n", $login, $userUA->getId())); // if the id provider does return groups, then revoke privileges if (is_array($data['_groups'])) { $appbox = $this->getAppbox(); $all_base_ids = []; foreach ($appbox->get_databoxes() as $databox) { foreach ($databox->get_collections() as $collection) { $all_base_ids[] = $collection->get_base_id(); } } $userACL = $ACLProvider->get($userUA); $userACL->revoke_access_from_bases($all_base_ids)->revoke_unused_sbas_rights(); $this->debug(sprintf("revoked from=%s \n", var_export($all_base_ids, true))); } } // here we should have a user if ($userUA) { $this->debug(sprintf("User id=%s \n", $userUA->getId())); // apply groups if (is_array($data['_groups'])) { $userACL = $ACLProvider->get($userUA); $models = []; // change groups to models foreach ($data['_groups'] as $grp) { $models[] = ['name' => $this->config['model-gpfx'] . $grp, 'autocreate' => true]; } // add "everyone-group" if(array_key_exists('everyone-group', $this->config) && trim($this->config['everyone-group']) !== '') { $models[] = ['name' => $this->config['model-gpfx'] . trim($this->config['everyone-group']), 'autocreate' => true]; } // add a specific model for the user $models[] = ['name' => $this->config['model-upfx'] . $login, 'autocreate' => false]; $this->debug(sprintf("models=%s \n", var_export($models, true))); // if we need those (in case of creation of a model), they will be set only once $metaModelUA = $metaModelBASES = $metaModelOwnerUA = null; foreach ($models as $model) { $this->debug(sprintf("searching model '%s' \n", $model['name'])); // we check if the model exits $modelUA = $userRepository->findByLogin($model['name']); if (!$modelUA) { if ($model['autocreate'] == true) { $this->debug(sprintf("model '%s' not found \n", $model['name'])); // the model does not exist, so create it // // if not already known, get the metamodel if ($metaModelUA === null) { $this->debug(sprintf("searching metamodel '%s'... \n", $this->config['metamodel'])); $metaModelUA = $userRepository->findByLogin($this->config['metamodel']); if ($metaModelUA) { $this->debug(sprintf("metaModelID=%s \n", print_r($metaModelUA->getId(), true))); // metamodel found, get some infos... // ... get acl $metaModelACL = $ACLProvider->get($metaModelUA); // ... then list of bases $metaModelBASES = $metaModelACL->get_granted_base(); // ... in fact we simply need an array of base_ids, and base_id is the keys of the array, so switch $metaModelBASES = array_keys($metaModelBASES); if ($metaModelUA->isTemplate()) { $metaModelOwnerUA = $metaModelUA->getTemplateOwner(); $this->debug(sprintf("metamodel is a model, owner_id=%s \n", print_r($metaModelOwnerUA->getId(), true))); } $this->debug(sprintf("metamodel granted on bases '%s' \n", print_r($metaModelBASES, true))); } else { $this->debug("metamodel not found \n"); $metaModelUA = false; // don't search again } } // now we can create the model only if we found the metamodel if ($metaModelUA) { $this->debug(sprintf("creating model '%s'... \n", $model['name'])); // create the model user... $modelUA = $userManipulator->createUser($model['name'], 'model_pwd', null, false); $this->debug(sprintf("model '%s' created with modelID=%s... \n", $model['name'], print_r($modelUA->getId(), true))); if ($metaModelOwnerUA) { $modelUA->setTemplateOwner($metaModelOwnerUA); $this->debug(sprintf("model '%s' set as model, owner_id=%s... \n", $model['name'], print_r($metaModelOwnerUA->getId(), true))); } // ... then copy acl of every sbas $modelACL = $ACLProvider->get($modelUA); $modelACL->apply_model($metaModelUA, $metaModelBASES); $this->debug(sprintf(" ... and granted on bases %s \n", print_r($metaModelBASES, true))); } } } else { // the model already exists $this->debug(sprintf("model '%s' already exists, id=%s \n", $model['name'], print_r($modelUA->getId(), true))); } // here we should have the model, except "user" models which are not automatically created if ($modelUA) { $this->debug(sprintf(" ... modelID=%s \n", print_r($modelUA->getId(), true))); // here we have the model so get some infos about it $modelACL = $ACLProvider->get($modelUA); $modelBASES = $modelACL->get_granted_base(); // ... in fact we simply need an array of base_ids, and base_id is the keys of the array, so switch $modelBASES = array_keys($modelBASES); $this->debug(sprintf("model granted on bases '%s' \n", print_r($modelBASES, true))); // ... then copy acl of every sbas $userACL->apply_model($modelUA, $modelBASES); $this->debug(sprintf("user '%s' granted on bases %s \n", $login, print_r($modelBASES, true))); } else { $this->debug(sprintf("no model '%s' \n", $model['name'])); } } $userACL->inject_rights(); } // now update infos of the user if (!is_null($data['firstname']) && ($v = trim($data['firstname'])) != '') { $userUA->setFirstName($v); } if (!is_null($data['firstname']) && ($v = trim($data['lastname'])) != '') { $userUA->setLastName($v); } $mail = ""; // mail is a special case try { if (($v = trim($data['email'])) != '') { $mail = $v; } } catch (Exception $e) { // no-op } if ($mail != $userUA->getEmail()) { try { $this->debug("unsetting former email of user"); $userManipulator->setEmail($userUA, null); if ($mail != "") { $this->debug(sprintf("setting email '%s' to user", $mail)); $dupUserUA = $userRepository->findByEmail($mail); if ($dupUserUA == null) { // ok we can set the mail $userManipulator->setEmail($userUA, $mail); $this->debug(sprintf("email '%s' set to user", $mail)); } else { $this->debug(sprintf("warning : another user (id=%s) already has email '%s', email not set", $dupUserUA->getId(), $mail)); } } } catch (Exception $e) { // no-op $this->debug(var_export($e->getMessage(), true)); } } else { $this->debug(sprintf("email '%s' does not change\n", $mail)); } // yes we are logged ! if (isset($this->config['exclusive']) && $this->config['exclusive'] == true) { // reset the password // if it is an existing user, the user cannot login from the default phraseanet login // cannot renew her password /** @var RandomGenerator $randomGenerator */ $randomGenerator = $this->getRandomGenerator(); $password = $randomGenerator->generateString(16); $userUA->setPassword($password); $userUA->setCanRenewPassword(false); } $this->debug(sprintf("returning user id=%s", $userUA->getId())); $ret = $userUA; // ->getId(); } return $ret; } private function filterGroups($groups) { $this->debug(sprintf("filtering openid groups :\n%s", print_r($groups, true))); $ret = []; if ($this->config['groupmask']) { $this->debug(sprintf("filtering groups with regexp : \"%s\"", $this->config['groupmask'])); foreach ($groups as $grp) { $matches = []; $retpreg = preg_match_all($this->config['groupmask'], $grp, $matches, PREG_SET_ORDER); $this->debug(sprintf("preg_match('%s', '%s', ...)\n - returned %s \n - matches = %s " , $this->config['groupmask'], $grp , print_r($retpreg, true), print_r($matches, true))); foreach ($matches as $match) { if (count($match)>0 && isset($match[1]) && !array_key_exists($match[1], $ret)) { $ret[] = $match[1]; } } } } else { $this->debug(sprintf("no groupmask defined, openid groups ignored")); } $this->debug(sprintf("filtered groups :\n%s", print_r($ret, true))); return empty($ret) ? '' : $ret ; } /** * {@inheritdoc} */ public function getIconURI() { return $this->iconUri ?: 'data:image/png;base64,' . 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAA' . 'AJZlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAAB' . 'AAAAUgExAAIAAAARAAAAWodpAAQAAAABAAAAbAAAAAAAAABIAAAAAQAAAEgAAAAB' . 'QWRvYmUgSW1hZ2VSZWFkeQAAAAOgAQADAAAAAQABAACgAgAEAAAAAQAAADCgAwAE' . 'AAAAAQAAADAAAAAAXukGzAAAAAlwSFlzAAALEwAACxMBAJqcGAAAActpVFh0WE1M' . 'OmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6' . 'bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1s' . 'bnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgt' . 'bnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAg' . 'ICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgog' . 'ICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYv' . 'MS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWRvYmUgSW1hZ2VSZWFk' . 'eTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4x' . 'PC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAg' . 'PC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KKS7NPQAADE5JREFUaAXtWQuMVcUZ/uY8' . '7vvui+WNAYHa2oqKiw/SWnaJ0ipqH4ZHmjTVGMFao00LVm2Dl9YXtVETpVYSX6m2' . 'tYhajU210V0KPqi7CALKrggUWeS9uOzufZzH9PvPvXdZ1t27rJCUpM5y7pyZM2fm' . '+/7/m3/ODMAX6QsLHJcF1HG9XeJlraEaFsOUJrW3w1MKukTzk+tR4zzYvRHpeli9' . '605E+YR2Wp+CVbC2o+9DtF1bd6EyodsTiV+qup1p8QpBG/SGdyLAn7A+dAqGgC92' . '2H4vrubVqpcaWi+v0u1/qWjteC7+o+Jz8QbJGMXy8eTHNQfEok3zYU1ZBkdAtN2L' . 'WkNhSVkE52VyQE4rB9XlCCe1HU76SDvu24hgQWx6+g1prxsptRq4xzM/uq0mHQ4m' . 'ic45sAB3Dt2P8crF3VEbs0kA7Wm4nLIG/2yxs+Nq3+30/Xg5LoDlrc6tMv/o2t5t' . 'agp2ypjiEVXHdz5HGrQH6mup8wZGFY67ewHisSrrNm25N5fFYBG4L3h4BdEHZIjh' . 'ZTCiZBPyoGzPM8O+ClV7hpfx00rpO40OLBHwBUmpwc6PY9ZhoHOCr2ugywmy7ebk' . '1eForCUZMm5TviHgxYLSXx58MWiKiVS+oAw+U9pwO+CYpo4aFbjDT2KzXosrCdwX' . '8CIrGYtvHVOS7ksmDq2a5tVQ5015nV87YpoXcu+tLPfOFcyO4Toq7FnKJi9THFBI' . 'gln0NFI84AceMEKFPOzBsHyJSa4RosxCgHcYr5kWFqjJWCc9HOv8KElAp1KGSqUC' . 'VG1zx41zTf+eaNybY1IOncpxKQlDhVyDOZiLRGj/AokCATUq2S2hQEYkYZKAsrrJ' . 'SkjVRpxRLAP4Hh6m+RdxfuwPiGjNsKu6G0tdz9Svq4rg3wSiu6446zdZL95cZlhz' . 'utKm39FleBSBxcuAY0E7ZvdFIRzpX26DS/woF/8FubDrTiI5y++E63vUVxl+rFW8' . 'Jdd4xo3SQsBrneoXZ4/RujuELrD+aO3aKZWrX3mx7MVbR+5PUxFjznJgdNjKygK0' . 'JGVDy8vkpPwLeXfZIEhKSI1OHOWBQEbiAXneOwWVY1wDO2wk+NBYuGlH1Q2zxw4Z' . '+34RU+9X+mS2uK4uqP/9jQtOX521R7Ze9XgmcuF8rbeut732PQwzFYyNR6wuHvhM' . 'ueAJCURi9fzF4QsTujcQqJHwfV8ZLsFH6vw269HM3/wZX1u88tUp0nZxQ0OfWPus' . 'REND0H+6eUv65YUL8MhjK+y1Y85U6rqlCI/+JvytG+HniEyXUTr8SiuQERI9iUCz' . 'jVha/BxcQiRPKBgg+BkCX1cD7iew7CgyQ36Hf2RvMua8q+3vNjbhvcO7u6RZw8qV' . 'R17pcdc3gdraoIkqLzOGTr4A5oZm/eoNP8ELqzag9fzvIzT3bsbDELzWZmivnCEk' . 'XiCSnw9wC/OCYsh3JCR6EAkqE/TkGE7aA7CM/TAqb8Fa+ync1DwCl6zbhFzmE315' . 'PI6kbfeNMd/zQPHWh9vRBb8qqSomfx2fPvES/nnNXXhrZxpdM3+FyPSFUAdb4B3c' . 'zvBRDe2GSMQIPFL0Rn7iitXF9Jw3BqWnBHgHTL0TVvlV2Jb4E+7cWYOaxq1o3P8R' . 'ZnJJt1RYpX0GnwE++wb8lJBgTXGSSBrhSWMRN018suRhtJ9xNk676jKMnf0oQh+8' . 'DmfD01BVxJicSAIHKC9a3OYk5ut56wv4EZRLK2yPXxCJ6Thgz8WLe4bgF9tbEXYP' . '4tJwhN8mUXQGSwRDk7w7QBqQgLwvWCSiaMeF52pEzpkEK5PBfxb8Fu3f+RZOmVmH' . 'IRPPBdY9A6f1LRjDRwgTzgcSURJxyikXmtIl+MRQZBIL8fqB8bi7ZR9Wd6zDxYkw' . '14Y40lrCfWAyGfaYUkl9BStMj24CIiz7/NTUlEL4vDPhrWvBtnkPYPPbu9BxzrUI' . 'X7QYhrsb/r4dbDiMchkOn+WItQ/msFvwjv8g5q2pxMxVa5HrbMXFsRhysoYF4HsM' . 'doy3x+YBdiZOkNQz97uylE0C9sgKpP/wGpoffxtDbrkEo+qeQGRXI5yWh2DTqKFh' . '1+BDcxqe3ODhzub3MDySRV1ZElnKsYvytAyDKpM5kh9jML+lCdAF2hLI0rM+CnxQ' . 'psA1AeiuHIwpwxmZNA4sfhIHp07C6DnTMGr6Q2gbpfD8riSuf+dDTsj9mFpVDicU' . 'x6eeRogh1mT3RaMMBnixbUkJFRvJAMVBjs5ZEl3JTHU8rg0Edf4ERLv2YuNPF+Hl' . 'lgTu2jgS1z/9Ciabh3B2sgxtXOAckj7K2MVOiwMOIi/tgV4d5X1wtCdk7Py0I3iq' . 'OZMJ4f3E6Wg44zyM35eFjnTwa2oiDnQoSqULUUtmFu1W4F7sTfo5ilSvsfsrDkgg' . 'b5ziMEc8EQAQCXFYWzM6cfStoTFYExqJXaEo/M4OxLkGHabOpW0mV4bOQ2Wo1mmU' . 'l3XRaR6r5Tvu88A+QmdAAtI0T6KQsyDzTURgMjRavNtjVaMpPAbvW0lEKakK7eEQ' . '32I4p7EJMhSGHbbY3kRbV4IS8lBV0U6CJCL9ayHy+dKABIrgi93LtknsblMuh1U5' . '1tLq79pVjPUWyn1uhbnt4naFLfKLmBIP2CFuYLhz4TPLkpU4gkOHy+H5WZSV7UfY' . '4qcue8xv5nqPWBy577wkAVGr2F3A5JcYDkO5uASw0RyB9+yh6DAiqCJwiUCOMrne' . '5YVR8BcUtw0IhWBaNmyGS4tlk5cQcbwY2g9XgSdHiMV3wzA4Z7QQCfwSjD7QT0kC' . '8nJgD5rcDERj4GN+L2w2hmK3iqOS0YTRnNtKERLtJzGNN6TBm7y2xTPiAYtX3gN5' . 'AiY9Y/ESMo4zGumuEYhEdpPoTr4rpgt398GbflNJAlxeGPR4oqB91YY4tmEItusk' . 'EqxNqiyxUkjEabIsH2vSWj45fFlVC8t24IGAgM3N2hHQliVE8gQsMjfMMNeUr9AA' . 'p1COW9nHTpbZTYntpLAqSYCvR3IMjs1uzNmCpEGLqXKdpX19ZBUlUbAyTAHP3sTw' . 'dJnPWc7NifRPYDKJ6QHOAd0tISFCAkeREDIMtWY164dzA7bXUZGPTTe7MxJ0NC34' . '/cyPDPnZ1NAQjH5I2f+u74x+sM6NRGzfUSE/62R9VzvUvOdxLvgOL94Hl1fIpezz' . 'YpikCXt6wBYZ2SQe5LyXeUFiIcmDujClplzbtlTFsHMiMVywNxadtFEA1tbenrdI' . 'L7R9EkjRiLyMZ7aub9m4682vluvMz3Ke86lLzbiegHbcAHxAgkSCOgEuJLgiS+5K' . 'nO9BIABbBNqTSKHOCnkk4cUrhlkk5bpdB5fErAnj//69metSPB1J9SOlfiVUJCH5' . 'ptY37p844sKnckjfYZuheaZvWYTNnbySI4+8EeRzopA8TnlXCNADBqUik1gsbHJN' . 'OKJ7kRClxAMiw7K8SDxpyzOd63rWsIxbl3/7lC3SXYoHDP2Bl+d9ekAeSEoRPDPF' . 'vZK9ZfeqfZtb/zXfcbwpWS9Tz7MOHk15BiXk0BtaJNVTSq7j5CVEnUcI3gqkc8QD' . 'VsjWlmU7oWjMSFQOpXCcd7WXu+jZS8fOEvDzHmm02YEqBV4w9usBeVhIugnBqZxR' . 'U1NjNjXVN7F++lnjZszxffOeiG2NE9nwkE1O7oL/2DB9A27GDaKReKBCPCCTOIg6' . 'gRdcy7StaEW17XV17PHSnYtWXH7qMhmvtr7eGrpvn142e4qD+VJTOpX0QK9X/aam' . 'JmcWZjGspIz12199Jhfb8eWcm77d9XI8KOL88Hk25bvctPHIMSsEuCaTQDyQEK1P' . 'qeR1PlR07ut0572VVYkvrbhsLMFrJeAb6urc5bNn59fQXgD6Kg6GQPD+cixn5ym/' . 'trbW2rRpU65p68u/9nx9WtZN/5maN/j9Y9IjdIdLleXnQNQO+ZSQE0lWmNFEuamz' . 'mecYhU9fcfm4mx/7xtDDgVy4pRHwfYEsVTdoAsXOGhoaZDBFWdlNW1/asebDF37g' . 'ec60nJt5h9X8aHYNHz4PIC0nFosZcerc8Jz12vdmPH/FqVc+P3NCS01B58vmUy7/' . '25QyxCNFDDOm/vCaCbh096Kf36d/u+aAnrq8ee/cl7ZdV3w+66/alOhSLJ80eYFE' . 'MZ7G70gtffCBlduXYslmHlHkk+i8eH/S5jU184Jo1BNgIBdqq2fdSX6fMmbNmmWK' . 'XMCV9CQH+wW8/18L/BeSV1YkHS6B9wAAAABJRU5ErkJggg=='; } public function getAccessToken($byRefresh = false) { if ($byRefresh) { $tokenInfo = $this->session->get('provider.token_info'); try { $url = sprintf("%s/realms/%s/protocol/openid-connect/token/", $this->config['base-url'], urlencode($this->config['realm-name']) ); $guzzleRequest = $this->client->post($url); $guzzleRequest->addPostFields([ 'grant_type' => "refresh_token", 'refresh_token' => $tokenInfo['refresh_token'], 'client_id' => $this->config['client-id'], 'client_secret' => $this->config['client-secret'], ]); $guzzleRequest->setHeader('Accept', 'application/json'); $response = $guzzleRequest->send(); $this->debug(); } catch (\Exception $e) { $this->debug($e->getMessage()); throw new NotAuthenticatedException('Guzzle error while authentication', $e->getCode(), $e); } if (200 !== $response->getStatusCode()) { $this->debug(); throw new NotAuthenticatedException('Error while retrieving user info, invalid status code.'); } $data = @json_decode($response->getBody(true), true); if (JSON_ERROR_NONE !== json_last_error()) { $this->debug(); throw new NotAuthenticatedException('Error while decoding token response, unable to parse JSON.'); } // override token information $this->session->set('provider.token_info', $data); $this->session->set($this->getId() . '.provider.access_token', $data['access_token']); } return $this->session->get($this->getId() . '.provider.access_token'); } public function getUserName() { return $this->session->get($this->getId() . ".provider.username"); } }