From 91a7b3d98c50af38fe914ee6046efa4524217212 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Fri, 22 Jan 2016 19:40:24 -0500 Subject: [PATCH 01/68] Add Login class to handle authorizations. Add onLoginPage event (allow other plugins to add to the login page) --- classes/Controller.php | 7 +- classes/Login.php | 252 ++++++++++++++ classes/LoginController.php | 6 +- classes/OAuthLoginController.php | 435 ------------------------ composer.json | 1 - login.php | 180 +--------- login.yaml | 36 +- templates/partials/login-form.html.twig | 34 +- 8 files changed, 284 insertions(+), 667 deletions(-) create mode 100644 classes/Login.php delete mode 100644 classes/OAuthLoginController.php diff --git a/classes/Controller.php b/classes/Controller.php index 84eab99..2c9fcf7 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -54,6 +54,11 @@ public function __construct(Grav $grav, $action, $post = null) { $this->grav = $grav; $this->action = $action; + if(!isset($this->grav['login'])){ + require_once __DIR__ . '/login.php'; + $this->grav['login'] = new Login($this->grav); + } + $this->login = $this->grav['login']; $this->post = $this->getPost($post); $this->rememberMe(); @@ -80,7 +85,7 @@ public function execute() try { $success = call_user_func(array($this, $method)); } catch (\RuntimeException $e) { - $this->setMessage($e->getMessage()); + $this->login->setMessage($e->getMessage()); } if (!$this->redirect && isset($redirect)) { diff --git a/classes/Login.php b/classes/Login.php new file mode 100644 index 0000000..ec2742f --- /dev/null +++ b/classes/Login.php @@ -0,0 +1,252 @@ +grav = $grav; + $this->config = $this->grav['config']; + //$this->route = $route; + $this->session = $this->grav['session']; + $this->user = $this->grav['user']; + + $this->uri = $this->grav['uri']; + } + + /** + * Add message into the session queue. + * + * @param string $msg + * @param string $type + */ + public function setMessage($msg, $type = 'info') + { + /** @var Message $messages */ + $messages = $this->grav['messages']; + $messages->add($msg, $type); + } + + /** + * Fetch and delete messages from the session queue. + * + * @param string $type + * + * @return array + */ + public function messages($type = null) + { + /** @var Message $messages */ + $messages = $this->grav['messages']; + + return $messages->fetch($type); + } + + /** + * Authenticate user. + * + * @param array $form Form fields. + * + * @return bool + */ + public function authenticate($form) + { + if (!$this->user->authenticated && isset($form['username']) && isset($form['password'])) { + $user = User::load($form['username']); + + //default to english if language not set + if (empty($user->language)) { + $user->set('language', 'en'); + } + + if ($user->exists()) { + $user->authenticated = true; + + // Authenticate user. + $result = $user->authenticate($form['password']); + + if ($result) { + $this->user = $this->session->user = $user; + + /** @var Grav $grav */ + $grav = $this->grav; + + $this->setMessage($this->grav['language']->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN', [$this->user->language]), 'info'); + + $redirect_route = $this->uri->route(); + $grav->redirect($redirect_route); + } + } + } + + return $this->authorize(); + } + + /** + * Checks user authorisation to the action. + * + * @param string $action + * + * @return bool + */ + public function authorize($action = 'admin.login') + { + $action = (array)$action; + + foreach ($action as $a) { + if ($this->user->authorize($a)) { + return true; + } + } + + return false; + } + + /** + * Create a new user file + * + * @param object $data + * + * @return bool + */ + public function register($data) + { + // Create user object and save it + $user = new User($data); + $username = $data['username']; + $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $user->file($file); + $user->save(); + $user = User::load($username); + + if ($data['state'] == 'enabled' && + $this->config->get('plugins.login.user_registration.options.login_after_registration', false)) { + + //Login user + $this->grav['session']->user = $user; + unset($this->grav['user']); + $this->grav['user'] = $user; + $user->authenticated = $user->authorize('site.login'); + } + + if ($this->config->get('plugins.login.user_registration.options.send_activation_email', false)) { + $this->sendActivationEmail($user); + } else { + if ($this->config->get('plugins.login.user_registration.options.send_welcome_email', false)) { + $this->sendWelcomeEmail($user); + } + if ($this->config->get('plugins.login.user_registration.options.send_notification_email', false)) { + $this->sendNotificationEmail($user); + } + } + + if ($redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration', false)) { + $this->grav->redirect($redirect); + } + } + + + /** + * Handle the email to notificate the user account creation to the site admin. + * + * @return bool True if the action was performed. + */ + public function sendNotificationEmail($user) + { + if (empty($user->email)) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); + } + + $sitename = $this->grav['config']->get('site.title', 'Website'); + + $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.NOTIFICATION_EMAIL_SUBJECT', $sitename]); + $content = $this->grav['language']->translate(['PLUGIN_LOGIN.NOTIFICATION_EMAIL_BODY', $sitename, $user->username, $user->email]); + $to = $this->grav['config']->get('plugins.email.from'); + + if (empty($to)) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_NOT_CONFIGURED')); + } + + $sent = LoginUtils::sendEmail($subject, $content, $to); + + if ($sent < 1) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_SENDING_FAILURE')); + } + + return true; + } + + /** + * Handle the email to welcome the new user + * + * @return bool True if the action was performed. + */ + public function sendWelcomeEmail($user) + { + if (empty($user->email)) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); + } + + $sitename = $this->grav['config']->get('site.title', 'Website'); + + $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.WELCOME_EMAIL_SUBJECT', $sitename]); + $content = $this->grav['language']->translate(['PLUGIN_LOGIN.WELCOME_EMAIL_BODY', $user->username, $sitename]); + $to = $user->email; + + $sent = LoginUtils::sendEmail($subject, $content, $to); + + if ($sent < 1) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_SENDING_FAILURE')); + } + + return true; + } + + /** + * Handle the email to activate the user account. + * + * @return bool True if the action was performed. + */ + protected function sendActivationEmail($user) + { + if (empty($user->email)) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); + } + + $token = md5(uniqid(mt_rand(), true)); + $expire = time() + 604800; // next week + $user->activation_token = $token . '::' . $expire; + $user->save(); + + $param_sep = $this->grav['config']->get('system.param_sep', ':'); + $activation_link = $this->grav['base_url_absolute'] . $this->config->get('plugins.login.route_activate') . '/token' . $param_sep . $token . '/username' . $param_sep . $user->username . '/nonce' . $param_sep . Utils::getNonce('user-activation'); + + $sitename = $this->grav['config']->get('site.title', 'Website'); + + $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_SUBJECT', $sitename]); + $content = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY', $user->username, $activation_link, $sitename]); + $to = $user->email; + + $sent = LoginUtils::sendEmail($subject, $content, $to); + + if ($sent < 1) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_SENDING_FAILURE')); + } + + return true; + } +} \ No newline at end of file diff --git a/classes/LoginController.php b/classes/LoginController.php index e49941d..adfae11 100644 --- a/classes/LoginController.php +++ b/classes/LoginController.php @@ -25,15 +25,15 @@ public function taskLogin() { $t = $this->grav['language']; if ($this->authenticate($this->post)) { - $this->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); + $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); $referrer = $this->grav['uri']->referrer('/'); $this->setRedirect($referrer); } else { $user = $this->grav['user']; if ($user->username) { - $this->setMessage($t->translate('PLUGIN_LOGIN.ACCESS_DENIED')); + $this->login->setMessage($t->translate('PLUGIN_LOGIN.ACCESS_DENIED')); } else { - $this->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_FAILED')); + $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_FAILED')); } } diff --git a/classes/OAuthLoginController.php b/classes/OAuthLoginController.php deleted file mode 100644 index 03d3b6a..0000000 --- a/classes/OAuthLoginController.php +++ /dev/null @@ -1,435 +0,0 @@ - - */ -class OAuthLoginController extends Controller -{ - /** - * @var string - */ - public $provider; - - /** - * @var \OAuth\Common\Storage\Session - */ - protected $storage; - - /** - * @var \OAuth\ServiceFactory - */ - protected $factory; - - /** - * @var \OAuth\Common\Service\AbstractService - */ - protected $service; - - /** - * @var string - */ - protected $prefix = 'oauth'; - - /** - * @var array - */ - protected $scopes = [ - 'github' => ['user'], - 'google' => ['userinfo_email', 'userinfo_profile'], - 'facebook' => ['public_profile'] - ]; - - /** - * Constructor. - * - * @param Grav $grav Grav instance - * @param string $action The name of the action - * @param array $post An array of values passed to the action - */ - public function __construct(Grav $grav, $action, $post = null) - { - parent::__construct($grav, ucfirst($action), $post); - - // Session storage - $this->storage = new Session(false, 'oauth_token', 'oauth_state'); - - /** @var $serviceFactory \OAuth\ServiceFactory */ - $this->factory = new ServiceFactory(); - - // Use curl client instead of fopen stream - if (extension_loaded('curl')) { - $this->factory->setHttpClient(new CurlCLient()); - } - } - - /** - * Performs an OAuth authentication - */ - public function execute() - { - /** @var \Grav\Common\Language\Language */ - $t = $this->grav['language']; - - $provider = strtolower($this->action); - $config = $this->grav['config']->get('plugins.login.oauth.providers.' . $this->action, []); - - if (isset($config['credentials'])) { - // Setup the credentials for the requests - $credentials = new Credentials( - $config['credentials']['key'], $config['credentials']['secret'], $this->grav['uri']->url(true) - ); - - // Instantiate service using the credentials, http client - // and storage mechanism for the token - $scope = isset($this->scopes[$provider]) ? $this->scopes[$provider] : []; - $this->service = $this->factory->createService($this->action, $credentials, $this->storage, $scope); - } - - if (!$this->service || empty($config)) { - $this->setMessage($t->translate(['PLUGIN_LOGIN.OAUTH_PROVIDER_NOT_SUPPORTED', $this->action])); - return true; - } - - // Check OAuth authentication status - $authenticated = parent::execute(); - if (is_bool($authenticated)) { - $this->reset(); - if ($authenticated) { - $this->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); - } else { - $this->setMessage($t->translate('PLUGIN_LOGIN.ACCESS_DENIED')); - } - - // Redirect to current URI - $referrer = $this->grav['uri']->url(true); - $this->setRedirect($referrer); - } elseif (!$this->grav['session']->oauth) { - $this->setMessage($t->translate(['PLUGIN_LOGIN.OAUTH_PROVIDER_NOT_SUPPORTED', $this->action])); - } - - return true; - } - - /** - * Reset state of OAuth authentication. - */ - public function reset() { - /** @var Grav\Common\Session */ - $session = $this->grav['session']; - - unset($session->oauth); - $this->storage->clearAllTokens(); - $this->storage->clearAllAuthorizationStates(); - } - - /** - * Implements a generic OAuth service provider authentication - * - * @param callable $callback A callable to call when OAuth authentication - * starts - * @param string $oauth OAuth version to be used for authentication - * - * @return null|User Returns a Grav user instance on success. - */ - protected function genericOAuthProvider($callback, $oauth = 'oauth2') - { - /** @var Grav\Common\Session */ - $session = $this->grav['session']; - - switch ($oauth) { - case 'oauth1': - if (empty($_GET['oauth_token']) && empty($_GET['oauth_verifier'])) { - // Extra request needed for OAuth1 to request a request token :-) - $token = $this->service->requestRequestToken(); - - // Create a state token to prevent request forgery. - // Store it in the session for later validation. - $redirect = $this->service->getAuthorizationUri([ - 'oauth_token' => $token->getRequestToken() - ]); - $this->setRedirect($redirect); - - // Update OAuth session - $session->oauth = $this->action; - } else { - $token = $this->storage->retrieveAccessToken($session->oauth); - - // This was a callback request from OAuth1 service, get the token - $this->service->requestAccessToken( - $_GET['oauth_token'], - $_GET['oauth_verifier'], - $token->getRequestTokenSecret() - ); - - return $callback(); - } - break; - - case 'oauth2': - default: - if (empty($_GET['code'])) { - // Create a state token to prevent request forgery (CSRF). - $state = sha1($this->getRandomBytes(1024, false)); - $redirect = $this->service->getAuthorizationUri([ - 'state' => $state - ]); - $this->setRedirect($redirect); - - // Update OAuth session - $session->oauth = $this->action; - - // Store CSRF in the session for later validation. - $this->storage->storeAuthorizationState($this->action, $state); - } else { - // Retrieve the CSRF state parameter - $state = isset($_GET['state']) ? $_GET['state'] : null; - - // This was a callback request from the OAuth2 service, get the token - $this->service->requestAccessToken($_GET['code'], $state); - - return $callback(); - } - break; - } - } - - /** - * Implements OAuth authentication for Facebook - * - * @return null|bool Returns a boolean on finished authentication. - */ - public function oauthFacebook() - { - return $this->genericOAuthProvider(function() { - // Send a request now that we have access token - $data = json_decode($this->service->request('/me'), true); - $email = isset($data['email']) ? $data['email'] : ''; - - // Authenticate OAuth user against Grav system. - return $this->authenticate($data['name'], $data['id'], $email); - }); - } - - /** - * Implements OAuth authentication for Google - * - * @return null|bool Returns a boolean on finished authentication. - */ - public function oauthGoogle() - { - return $this->genericOAuthProvider(function() { - // Get username, email and language - $data = json_decode($this->service->request('userinfo'), true); - - $username = $data['given_name'] . ' ' . $data['family_name']; - if (preg_match('~[\w\s]+\((\w+)\)~i', $data['name'], $matches)) { - $username = $matches[1]; - } - $lang = isset($data['lang']) ? $data['lang'] : ''; - - // Authenticate OAuth user against Grav system. - return $this->authenticate($username, $data['id'], $data['email'], $lang); - }); - } - - /** - * Implements OAuth authentication for GitHub - * - * @return null|bool Returns a boolean on finished authentication. - */ - public function oauthGithub() - { - return $this->genericOAuthProvider(function() { - // Get username, email and language - $user = json_decode($this->service->request('user'), true); - $emails = json_decode($this->service->request('user/emails'), true); - - // Authenticate OAuth user against Grav system. - return $this->authenticate($user['login'], $user['id'], reset($emails)); - }); - } - - /** - * Implements OAuth authentication for Twitter - * - * @return null|bool Returns a boolean on finished authentication. - */ - public function oauthTwitter() - { - return $this->genericOAuthProvider(function() { - // Get username, email and language - $data = json_decode( - $this->service->request('account/verify_credentials.json?include_email=true'), - true); - $lang = isset($data['lang']) ? $data['lang'] : ''; - - // Authenticate OAuth user against Grav system. - return $this->authenticate($data['screen_name'], $data['id'], '', $lang); - }, 'oauth1'); - } - - /** - * Authenticate user. - * - * @param string $username The username of the OAuth user - * @param string $email The email of the OAuth user - * @param string $language Language - * - * @return bool True if user was authenticated - */ - protected function authenticate($username, $id, $email, $language = '') - { - $accountFile = $this->grav['inflector']->underscorize($username); - $user = User::load(strtolower("$accountFile.{$this->action}")); - - if ($user->exists()) { - // Update username (hide OAuth from user) - $user->set('username', $username); - - $password = md5($id); - $authenticated = $user->authenticate($password); - } else { - /** @var User $user */ - $user = $this->grav['user']; - - // Check user rights - if (!$user->authenticated) { - $oauthUser = $this->grav['config']->get('plugins.login.oauth.user', []); - - // Create new user from OAuth request - $user = $this->createUser([ - 'id' => $id, - 'username' => $username, - 'email' => $email, - 'lang' => $language, - 'access' => $oauthUser['access'] - ], $oauthUser['autocreate']); - } - - // Authenticate user against oAuth rules - $authenticated = $user->authenticated; - } - - // Store user in session - if ($authenticated) { - $this->grav['session']->user = $user; - - unset($this->grav['user']); - $this->grav['user'] = $user; - } - - return $authenticated; - } - - /** - * Create user. - * - * @param string $data['username'] The username of the OAuth user - * @param string $data['password'] The unique id of the Oauth user - * setting as password - * @param string $data['email'] The email of the OAuth user - * @param string $data['language'] Language - * @param bool $save Save user - * - * @return User A user object - */ - protected function createUser($data, $save = false) - { - /** @var User $user */ - $user = $this->grav['user']; - - $accountFile = $this->grav['inflector']->underscorize($data['username']); - $accountFile = $this->grav['locator']->findResource('user://accounts/' . strtolower("$accountFile.{$this->action}") . YAML_EXT, true, true); - - $user->set('username', $data['username']); - $user->set('password', md5($data['id'])); - $user->set('email', $data['email']); - $user->set('lang', $data['lang']); - - // Set access rights - $user->join('access', - $this->grav['config']->get('plugins.login.oauth.user.access', []) - ); - - // Authorize OAuth user to access page(s) - $user->authenticated = $user->authorize('site.login'); - - if ($save) { - $user->file(CompiledYamlFile::instance($accountFile)); - $user->save(); - } - - return $user; - } - - /** - * Generates Random Bytes for the given $length. - * - * @param int $length The number of bytes to generate - * @param bool $secure Return cryptographic secure string or not - * - * @return string - * - * @throws InvalidArgumentException when an invalid length is specified. - * @throws RuntimeException when no secure way of making bytes is posible - */ - protected function getRandomBytes($length = 0, $secure = true) - { - if ($length < 1) { - throw new \InvalidArgumentException('The length parameter must be a number greater than zero!'); - } - - /** - * Our primary choice for a cryptographic strong randomness function is - * openssl_random_pseudo_bytes. - */ - if (function_exists('openssl_random_pseudo_bytes')) { - $bytes = openssl_random_pseudo_bytes($length, $sec); - if ($sec === true) { - return $bytes; - } - } - - /** - * If mcrypt extension is available then we use it to gather entropy from - * the operating system's PRNG. This is better than reading /dev/urandom - * directly since it avoids reading larger blocks of data than needed. - * Older versions of mcrypt_create_iv may be broken or take too much time - * to finish so we only use this function with PHP 5.3.7 and above. - * @see https://bugs.php.net/bug.php?id=55169 - */ - if (function_exists('mcrypt_create_iv') && - (strtolower(substr(PHP_OS, 0, 3)) !== 'win' || - version_compare(PHP_VERSION, '5.3.7') >= 0)) { - $bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); - if ($bytes !== false) { - return $bytes; - } - } - - if ($secure) { - throw new \RuntimeException('There is no possible way of making secure bytes'); - } - - /** - * Fallback (not really secure, but better than nothing) - */ - return hex2bin(substr(str_shuffle(str_repeat('0123456789abcdef', $length*16)), 0, $length)); - } -} diff --git a/composer.json b/composer.json index 181805a..78751cc 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,6 @@ }, "require": { "php": ">=5.4.0", - "lusitanian/oauth": "0.8.*", "birke/rememberme": "1.*" }, "autoload": { diff --git a/login.php b/login.php index da3d82a..20d885a 100644 --- a/login.php +++ b/login.php @@ -79,7 +79,7 @@ public function initialize() throw new \Exception('Login Plugin failed to load. Composer dependencies not met.'); } require_once $autoload; - + // Define session message service. $this->grav['messages'] = function ($c) { $session = $c['session']; @@ -90,7 +90,7 @@ public function initialize() return $session->messages; }; - + // Define current user service. $this->grav['user'] = function ($c) { $session = $c['session']; @@ -126,15 +126,14 @@ public function initialize() return $session->user; }; - - // Manage OAuth login - $task = !empty($_POST['task']) ? $_POST['task'] : $uri->param('task'); - if (!$task && isset($_POST['oauth']) || (!empty($_GET) && $session->oauth)) { - $this->oauthController(); - } - - // Aborted OAuth authentication (invalidate it) - unset($session->oauth); + + + //Initialize Login Object + require_once __DIR__ . '/classes/login.php'; + $this->login = new Login($this->grav); + + //Store Login Object in Grav + $this->grav['login'] = $this->login; $admin_route = $this->config->get('plugins.admin.route'); @@ -301,10 +300,10 @@ public function handleUserActivation() $messages->add($message, 'info'); if ($this->config->get('plugins.login.user_registration.options.send_welcome_email', false)) { - $this->sendWelcomeEmail($user); + $this->login->sendWelcomeEmail($user); } if ($this->config->get('plugins.login.user_registration.options.send_notification_email', false)) { - $this->sendNotificationEmail($user); + $this->login->sendNotificationEmail($user); } if ($this->config->get('plugins.login.user_registration.options.login_after_registration', false)) { @@ -368,21 +367,6 @@ public function loginController() $controller->redirect(); } - /** - * Initialize OAuth login controller - */ - public function oauthController() - { - /** @var Uri $uri */ - $uri = $this->grav['uri']; - $oauth = !empty($_POST['oauth']) ? $_POST['oauth'] : $uri->param('oauth'); - $oauth = $oauth ?: $this->grav['session']->oauth; - $post = !empty($_POST) ? $_POST : []; - - $controller = new Login\OAuthLoginController($this->grav, $oauth, $post); - $controller->execute(); - $controller->redirect(); - } /** * Authorize Page @@ -479,23 +463,14 @@ public function onTwigSiteVariables() { /** @var Twig $twig */ $twig = $this->grav['twig']; + + $this->grav->fireEvent('onLoginPage'); $extension = $this->grav['uri']->extension(); $extension = $extension ?: 'html'; if (!$this->authenticated) { $twig->template = "login." . $extension . ".twig"; - - $providers = []; - foreach ($this->config->get('plugins.login.oauth.providers') as $provider => $options) { - if ($options['enabled'] && isset($options['credentials'])) { - $providers[$provider] = $options['credentials']; - } - } - $twig->twig_vars['oauth'] = [ - 'enabled' => $this->config->get('plugins.login.oauth.enabled'), - 'providers' => $providers - ]; } // add CSS for frontend if required @@ -544,6 +519,7 @@ public function onFormProcessed(Event $event) $data = []; $username = $form->value('username'); + $data['username'] = $username; if (file_exists($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT))) { $this->grav->fireEvent('onFormValidationError', @@ -591,138 +567,16 @@ public function onFormProcessed(Event $event) unset($data['password2']); } - // Don't store the username: that is part of the filename - unset($data['username']); if ($this->config->get('plugins.login.user_registration.options.set_user_disabled', false)) { $data['state'] = 'disabled'; } else { $data['state'] = 'enabled'; } - - // Create user object and save it - $user = new User($data); - $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); - $user->file($file); - $user->save(); - $user = User::load($username); - - if ($data['state'] == 'enabled' && - $this->config->get('plugins.login.user_registration.options.login_after_registration', false)) { - - //Login user - $this->grav['session']->user = $user; - unset($this->grav['user']); - $this->grav['user'] = $user; - $user->authenticated = $user->authorize('site.login'); - } - - if ($this->config->get('plugins.login.user_registration.options.send_activation_email', false)) { - $this->sendActivationEmail($user); - } else { - if ($this->config->get('plugins.login.user_registration.options.send_welcome_email', false)) { - $this->sendWelcomeEmail($user); - } - if ($this->config->get('plugins.login.user_registration.options.send_notification_email', false)) { - $this->sendNotificationEmail($user); - } - } - - if ($redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration', false)) { - $this->grav->redirect($redirect); - } - + + $this->login->register($data); break; } } - /** - * Handle the email to notificate the user account creation to the site admin. - * - * @return bool True if the action was performed. - */ - protected function sendNotificationEmail($user) - { - if (empty($user->email)) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); - } - - $sitename = $this->grav['config']->get('site.title', 'Website'); - - $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.NOTIFICATION_EMAIL_SUBJECT', $sitename]); - $content = $this->grav['language']->translate(['PLUGIN_LOGIN.NOTIFICATION_EMAIL_BODY', $sitename, $user->username, $user->email]); - $to = $this->grav['config']->get('plugins.email.from'); - - if (empty($to)) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_NOT_CONFIGURED')); - } - - $sent = LoginUtils::sendEmail($subject, $content, $to); - - if ($sent < 1) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_SENDING_FAILURE')); - } - - return true; - } - - /** - * Handle the email to welcome the new user - * - * @return bool True if the action was performed. - */ - protected function sendWelcomeEmail($user) - { - if (empty($user->email)) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); - } - - $sitename = $this->grav['config']->get('site.title', 'Website'); - - $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.WELCOME_EMAIL_SUBJECT', $sitename]); - $content = $this->grav['language']->translate(['PLUGIN_LOGIN.WELCOME_EMAIL_BODY', $user->username, $sitename]); - $to = $user->email; - - $sent = LoginUtils::sendEmail($subject, $content, $to); - - if ($sent < 1) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_SENDING_FAILURE')); - } - - return true; - } - - /** - * Handle the email to activate the user account. - * - * @return bool True if the action was performed. - */ - protected function sendActivationEmail($user) - { - if (empty($user->email)) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); - } - - $token = md5(uniqid(mt_rand(), true)); - $expire = time() + 604800; // next week - $user->activation_token = $token . '::' . $expire; - $user->save(); - - $param_sep = $this->grav['config']->get('system.param_sep', ':'); - $activation_link = $this->grav['base_url_absolute'] . $this->config->get('plugins.login.route_activate') . '/token' . $param_sep . $token . '/username' . $param_sep . $user->username . '/nonce' . $param_sep . Utils::getNonce('user-activation'); - - $sitename = $this->grav['config']->get('site.title', 'Website'); - - $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_SUBJECT', $sitename]); - $content = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY', $user->username, $activation_link, $sitename]); - $to = $user->email; - - $sent = LoginUtils::sendEmail($subject, $content, $to); - - if ($sent < 1) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.EMAIL_SENDING_FAILURE')); - } - - return true; - } } diff --git a/login.yaml b/login.yaml index 0a8eac5..5c26e44 100644 --- a/login.yaml +++ b/login.yaml @@ -34,38 +34,4 @@ user_registration: rememberme: enabled: true timeout: 1800 # Timeout in seconds - name: grav-rememberme # Name prefix of the session cookie - -oauth: - enabled: false - - user: - autocreate: false - access: - site: - login: true - - providers: - Facebook: - enabled: false - credentials: - key: - secret: - - Google: - enabled: false - credentials: - key: - secret: - - GitHub: - enabled: false - credentials: - key: - secret: - - Twitter: - enabled: false - credentials: - key: - secret: + name: grav-rememberme # Name prefix of the session cookie \ No newline at end of file diff --git a/templates/partials/login-form.html.twig b/templates/partials/login-form.html.twig index 57b9a94..84ae806 100644 --- a/templates/partials/login-form.html.twig +++ b/templates/partials/login-form.html.twig @@ -6,35 +6,11 @@ {% include 'partials/messages.html.twig' %}
- {% if oauth.enabled %} -
- {# Create hidden duplicate of submit button to designate it as default #} - - - {# Show OAuth authentication providers #} -

{{ 'PLUGIN_LOGIN.OAUTH_CONNECT_MESSAGE'|t }} - {% if oauth.providers|count > 4 %} - {{ 'PLUGIN_LOGIN.OR'|t }}

- -
    - {% for provider,credentials in oauth.providers[4:] %} - {% set icon = icons[provider]|default(provider|lower) %} -
  • - {% endfor %} -
- {% else %} -

- {% endif %} - -
    - {% for provider,credentials in oauth.providers[:4] %} - {% set icon = icons[provider]|default(provider|lower) %} -
  • - {% endfor %} -
-
- {{ 'PLUGIN_LOGIN.OR'|t }} -

{{ 'PLUGIN_LOGIN.OAUTH_SIGNIN'|t }}

+ {% if grav.twig.plugins_hooked_loginPage %} + {% for label in grav.twig.plugins_hooked_loginPage %} + + {% include label %} + {% endfor %} {% endif %} {% for field in page.header.form.fields %} From 586739ea9c842b60c456b2203ed4a8746395a944 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Fri, 22 Jan 2016 19:43:33 -0500 Subject: [PATCH 02/68] Fix capitalization --- login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/login.php b/login.php index 20d885a..a2b0fe3 100644 --- a/login.php +++ b/login.php @@ -129,7 +129,7 @@ public function initialize() //Initialize Login Object - require_once __DIR__ . '/classes/login.php'; + require_once __DIR__ . '/classes/Login.php'; $this->login = new Login($this->grav); //Store Login Object in Grav From cfac00cdb3a5ef9906307267c9b0e772f55fcd77 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Fri, 22 Jan 2016 21:56:56 -0500 Subject: [PATCH 03/68] Fix logout errors --- classes/Controller.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/classes/Controller.php b/classes/Controller.php index 2c9fcf7..d90e89a 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -54,11 +54,7 @@ public function __construct(Grav $grav, $action, $post = null) { $this->grav = $grav; $this->action = $action; - if(!isset($this->grav['login'])){ - require_once __DIR__ . '/login.php'; - $this->grav['login'] = new Login($this->grav); - } - $this->login = $this->grav['login']; + $this->login = isset($this->grav['login'])?$this->grav['login']:''; $this->post = $this->getPost($post); $this->rememberMe(); From 12a60ae4eb7b35a5bb95a4ef886bf496d2626792 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Fri, 22 Jan 2016 22:25:56 -0500 Subject: [PATCH 04/68] Update Docs and Blueprints --- README.md | 54 ---------------- blueprints.yaml | 159 ++---------------------------------------------- 2 files changed, 4 insertions(+), 209 deletions(-) diff --git a/README.md b/README.md index 3bdfbd4..14eec07 100644 --- a/README.md +++ b/README.md @@ -332,60 +332,6 @@ You can set the "Redirect after registration" option in the Login plugin, or as ``` -# OAuth - -You can add OAuth providers to the login plugin as another method to have users on your site. To enable OAuth change `oauth.enabled` to `true` in `login.yaml`. By default OAuth allows users to login though they do not create an account file for the user. If you want an account file created (ex: for tracking purposes) change `oauth.user.autocreate` to `true` in `login.yaml`. ->Note: OAuth has not been tested with Grav's multilang feature! Due to this, certain OAuth providers may not function properly on multilang sites - ->IMPORTANT: `localhost` may NOT be used for callback and allowed URLs when creating OAuth provider applications due to certificate verification issues. Some services allow other URLs and it may be possible to add custom domains pointing to 127.0.0.1 in your hosts file and point applications there. - -## Facebook - -Visit https://developers.facebook.com/quickstarts/?platform=web and create an app name then click **Create New Facebook App ID.** - -Choose a category most similar to your business then click **Create App ID.** - -Scroll down on the next screen to the section titled **Tell us about your website.** Input a URL for the site (no need to include the protocol). Click **Next** - -Click **Skip Quick Start** Copy the **App ID** and **App Secret** into `login.yaml` - -On the left hand side click **Settings** -In the **Basic** tab add your domain into the **App Domains** section as well as enter a contact email (required for facebook developer program). In the **Advanced** tab scroll down to the **Client OAuth Settings** Make sure that **Client OAuth Login** is enabled as well as **Web OAuth Login** is enabled. In the **Valid OAuth redirect URIs** section add the routes of all pages that are protected by login. This includes the domains. EX: `http://getgrav.org/`, `http://getgrav.org/login`, `http://getgrav.org/en/login`, and `http://getgrav.org/protected/page/route` - - -## Github - -Visit Github's [Developer Applications Console](https://github.com/settings/developers) and press button **Register new application** (login if necesarry). ![](assets/github/github.png) - -Fill out the name and the URL (can be anything) and fill in the **callback**, which must be equal to where your grav site is located, generally just the host, i.e. `http://getgrav.org`. ![](assets/github/github_2.png) - -Copy **Client ID** and **client secret** into login.yaml under Github. ![](assets/github/github_3.png)Be sure to change `Github.enabled` to `true` - -## Google - -Visit the [Google Developers Console](https://console.developers.google.com) (sign in with a google account, preferably your businesses gmail). - -Select **Create Project** and give the project a name (can be anything). Click **Create**. ![](assets/google/google.png) - -When it's finished creating in the left hand menu choose **Credentials** under **APIs & Auth** (you may need to click **APIs & Auth** in order to display **Credntials**). ![](assets/google/google_3.png) - -Under **Add credentials** (center of screen) select **OAuth 2.0 client ID**.![](assets/google/google_4.png) - -Then select **Configure consent screen** in the top right corner. ![](assets/google/google_5.png) - -The only requirement is **Product name** which should be the name of your website/business (not a url). You may fill in the other options as you want on the consent screen. (The consent screen can also be changed later). ![](assets/google/google_6.png) - -Then once you save the consent screen select **Web application** from the radio buttons and fill in the fields. **Name** being name of product/business. **Authorized Javascript origins** is the root domain name of the login page (no routes or wildcards) such as `http://getgrav.org`. - -If needed, enter multiple sub domains, creating an entry for each. **Authorized redirect URIs** include the **same** Authorized Javascript origins used along with the **route** to the login page such as `http://getgrav.org/login`. Click **create**. - -![](assets/google/google_7.png) - -Copy **Client ID** and **client secret** into login.yaml under Google. ![](assets/google/google_8.png)Be sure to change `Google.enabled` to `true` - -## Twitter - -Login if necessary. Create a [new Twitter App](https://apps.twitter.com/app/new) , fill out name, application website, choose "Browser" as application type, choose the callback URL like above, default access type can be set to read-only, click on "Register application" and then you should be directed to your new application with the Client ID and secret ready to be copied and pasted into the YAML file. # Known issues diff --git a/blueprints.yaml b/blueprints.yaml index 64613a8..516e1d8 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -33,7 +33,7 @@ form: enabled: type: hidden - label: PLUGIN_ADMIN.PLUGIN_STATUS + label: PLUGIN_LOGIN.PLUGIN_STATUS highlight: 1 default: 1 options: @@ -74,8 +74,8 @@ form: default: 0 help: "Check for parent access rules if no rules are defined" options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED + 1: Enabled + 0: Disabled validate: type: bool @@ -229,155 +229,4 @@ form: 1: PLUGIN_ADMIN.YES 0: PLUGIN_ADMIN.NO validate: - type: bool - - oauth: - type: tab - title: PLUGIN_LOGIN.OAUTH_SECTION - - fields: - oauth.enabled: - type: toggle - label: PLUGIN_LOGIN.OAUTH_ENABLE - highlight: 0 - default: 0 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - oauth.user.autocreate: - type: toggle - label: PLUGIN_LOGIN.OAUTH_USER_AUTOCREATE - highlight: 0 - default: 0 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - oauth.user.access: - type: array - label: PLUGIN_LOGIN.OAUTH_ACCESS - placeholder_key: signin.login - placeholder_value: true - - oauth.providers: - type: section - title: PLUGIN_LOGIN.OAUTH_PROVIDER_SECTION - underline: true - - fields: - oauth.providers.Facebook: - type: section - title: PLUGIN_LOGIN.FACEBOOK - - fields: - oauth.providers.Facebook.enabled: - type: toggle - label: PLUGIN_LOGIN.OAUTH_PROVIDER_FACEBOOK - highlight: 1 - default: 0 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - oauth.providers.Facebook.credentials.key: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_ID - validate: - type: string - - oauth.providers.Facebook.credentials.secret: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_SECRET - validate: - type: string - - oauth.providers.Google: - type: section - title: PLUGIN_LOGIN.GOOGLE - - fields: - oauth.providers.Google.enabled: - type: toggle - label: PLUGIN_LOGIN.OAUTH_PROVIDER_GOOGLE - highlight: 1 - default: 0 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - oauth.providers.Google.credentials.key: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_ID - validate: - type: string - - oauth.providers.Google.credentials.secret: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_SECRET - validate: - type: string - - oauth.providers.GitHub: - type: section - title: PLUGIN_LOGIN.GITHUB - - fields: - oauth.providers.GitHub.enabled: - type: toggle - label: PLUGIN_LOGIN.OAUTH_PROVIDER_GITHUB - highlight: 1 - default: 0 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - oauth.providers.GitHub.credentials.key: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_ID - validate: - type: string - - oauth.providers.GitHub.credentials.secret: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_SECRET - validate: - type: string - - oauth.providers.Twitter: - type: section - title: PLUGIN_LOGIN.TWITTER - - fields: - oauth.providers.Twitter.enabled: - type: toggle - label: PLUGIN_LOGIN.OAUTH_PROVIDER_TWITTER - highlight: 1 - default: 0 - options: - 1: PLUGIN_ADMIN.ENABLED - 0: PLUGIN_ADMIN.DISABLED - validate: - type: bool - - oauth.providers.Twitter.credentials.key: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_ID - validate: - type: string - - oauth.providers.Twitter.credentials.secret: - type: text - label: PLUGIN_LOGIN.OAUTH_CLIENT_SECRET - validate: - type: string + type: bool \ No newline at end of file From 70b8e711d37a23601ad52d4e16243258ebfe24b0 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 8 Feb 2016 09:52:28 +0100 Subject: [PATCH 05/68] Composer update. Drop OAuth lib --- composer.lock | 63 ++ vendor/composer/ClassLoader.php | 16 +- vendor/{lusitanian/oauth => composer}/LICENSE | 5 +- vendor/composer/autoload_namespaces.php | 2 - vendor/composer/autoload_real.php | 5 - vendor/composer/installed.json | 69 -- vendor/lusitanian/oauth/.gitignore | 6 - vendor/lusitanian/oauth/.scrutinizer.yml | 37 -- vendor/lusitanian/oauth/.travis.yml | 21 - vendor/lusitanian/oauth/README.md | 123 ---- vendor/lusitanian/oauth/composer.json | 45 -- vendor/lusitanian/oauth/composer.lock | 610 ------------------ vendor/lusitanian/oauth/phpunit.xml.dist | 45 -- .../oauth/src/OAuth/Common/AutoLoader.php | 81 --- .../src/OAuth/Common/Consumer/Credentials.php | 60 -- .../Common/Consumer/CredentialsInterface.php | 24 - .../src/OAuth/Common/Exception/Exception.php | 10 - .../Common/Http/Client/AbstractClient.php | 73 --- .../Common/Http/Client/ClientInterface.php | 32 - .../OAuth/Common/Http/Client/CurlClient.php | 142 ---- .../OAuth/Common/Http/Client/StreamClient.php | 95 --- .../Http/Exception/TokenResponseException.php | 12 - .../oauth/src/OAuth/Common/Http/Uri/Uri.php | 408 ------------ .../src/OAuth/Common/Http/Uri/UriFactory.php | 168 ----- .../Common/Http/Uri/UriFactoryInterface.php | 42 -- .../OAuth/Common/Http/Uri/UriInterface.php | 133 ---- .../OAuth/Common/Service/AbstractService.php | 100 --- .../OAuth/Common/Service/ServiceInterface.php | 49 -- .../AuthorizationStateNotFoundException.php | 10 - .../Storage/Exception/StorageException.php | 12 - .../Exception/TokenNotFoundException.php | 10 - .../oauth/src/OAuth/Common/Storage/Memory.php | 139 ---- .../oauth/src/OAuth/Common/Storage/Redis.php | 230 ------- .../src/OAuth/Common/Storage/Session.php | 204 ------ .../OAuth/Common/Storage/SymfonySession.php | 200 ------ .../Common/Storage/TokenStorageInterface.php | 98 --- .../src/OAuth/Common/Token/AbstractToken.php | 128 ---- .../Token/Exception/ExpiredTokenException.php | 12 - .../src/OAuth/Common/Token/TokenInterface.php | 64 -- .../OAuth/OAuth1/Service/AbstractService.php | 320 --------- .../src/OAuth/OAuth1/Service/BitBucket.php | 96 --- .../oauth/src/OAuth/OAuth1/Service/Etsy.php | 132 ---- .../oauth/src/OAuth/OAuth1/Service/FitBit.php | 96 --- .../OAuth/OAuth1/Service/FiveHundredPx.php | 120 ---- .../oauth/src/OAuth/OAuth1/Service/Flickr.php | 133 ---- .../src/OAuth/OAuth1/Service/QuickBooks.php | 120 ---- .../src/OAuth/OAuth1/Service/Redmine.php | 96 --- .../src/OAuth/OAuth1/Service/ScoopIt.php | 96 --- .../OAuth/OAuth1/Service/ServiceInterface.php | 45 -- .../oauth/src/OAuth/OAuth1/Service/Tumblr.php | 96 --- .../src/OAuth/OAuth1/Service/Twitter.php | 123 ---- .../oauth/src/OAuth/OAuth1/Service/Xing.php | 97 --- .../oauth/src/OAuth/OAuth1/Service/Yahoo.php | 131 ---- .../UnsupportedHashAlgorithmException.php | 12 - .../src/OAuth/OAuth1/Signature/Signature.php | 132 ---- .../OAuth1/Signature/SignatureInterface.php | 28 - .../src/OAuth/OAuth1/Token/StdOAuth1Token.php | 75 --- .../src/OAuth/OAuth1/Token/TokenInterface.php | 41 -- .../OAuth/OAuth2/Service/AbstractService.php | 364 ----------- .../oauth/src/OAuth/OAuth2/Service/Amazon.php | 97 --- .../oauth/src/OAuth/OAuth2/Service/Bitly.php | 111 ---- .../src/OAuth/OAuth2/Service/Bitrix24.php | 118 ---- .../oauth/src/OAuth/OAuth2/Service/Box.php | 88 --- .../oauth/src/OAuth/OAuth2/Service/Buffer.php | 151 ----- .../src/OAuth/OAuth2/Service/Dailymotion.php | 129 ---- .../oauth/src/OAuth/OAuth2/Service/Deezer.php | 121 ---- .../src/OAuth/OAuth2/Service/Delicious.php | 139 ---- .../src/OAuth/OAuth2/Service/DeviantArt.php | 99 --- .../src/OAuth/OAuth2/Service/Dropbox.php | 111 ---- .../src/OAuth/OAuth2/Service/EveOnline.php | 100 --- .../Exception/InvalidAccessTypeException.php | 12 - .../InvalidAuthorizationStateException.php | 10 - .../Exception/InvalidScopeException.php | 17 - .../MissingRefreshTokenException.php | 17 - .../src/OAuth/OAuth2/Service/Facebook.php | 208 ------ .../src/OAuth/OAuth2/Service/Foursquare.php | 81 --- .../oauth/src/OAuth/OAuth2/Service/GitHub.php | 216 ------- .../oauth/src/OAuth/OAuth2/Service/Google.php | 190 ------ .../src/OAuth/OAuth2/Service/Harvest.php | 157 ----- .../oauth/src/OAuth/OAuth2/Service/Heroku.php | 123 ---- .../oauth/src/OAuth/OAuth2/Service/Hubic.php | 155 ----- .../src/OAuth/OAuth2/Service/Instagram.php | 85 --- .../src/OAuth/OAuth2/Service/JawboneUP.php | 144 ----- .../src/OAuth/OAuth2/Service/Linkedin.php | 103 --- .../src/OAuth/OAuth2/Service/Mailchimp.php | 114 ---- .../src/OAuth/OAuth2/Service/Microsoft.php | 120 ---- .../oauth/src/OAuth/OAuth2/Service/Nest.php | 106 --- .../src/OAuth/OAuth2/Service/Netatmo.php | 117 ---- .../OAuth2/Service/ParrotFlowerPower.php | 142 ---- .../oauth/src/OAuth/OAuth2/Service/Paypal.php | 103 --- .../src/OAuth/OAuth2/Service/Pinterest.php | 117 ---- .../oauth/src/OAuth/OAuth2/Service/Pocket.php | 125 ---- .../oauth/src/OAuth/OAuth2/Service/Reddit.php | 114 ---- .../src/OAuth/OAuth2/Service/RunKeeper.php | 105 --- .../src/OAuth/OAuth2/Service/Salesforce.php | 92 --- .../OAuth/OAuth2/Service/ServiceInterface.php | 38 -- .../src/OAuth/OAuth2/Service/SoundCloud.php | 77 --- .../src/OAuth/OAuth2/Service/Spotify.php | 112 ---- .../oauth/src/OAuth/OAuth2/Service/Strava.php | 147 ----- .../src/OAuth/OAuth2/Service/Ustream.php | 98 --- .../oauth/src/OAuth/OAuth2/Service/Vimeo.php | 156 ----- .../src/OAuth/OAuth2/Service/Vkontakte.php | 109 ---- .../oauth/src/OAuth/OAuth2/Service/Yahoo.php | 76 --- .../oauth/src/OAuth/OAuth2/Service/Yammer.php | 82 --- .../src/OAuth/OAuth2/Token/StdOAuth2Token.php | 13 - .../src/OAuth/OAuth2/Token/TokenInterface.php | 9 - .../oauth/src/OAuth/ServiceFactory.php | 240 ------- .../lusitanian/oauth/src/OAuth/bootstrap.php | 13 - 108 files changed, 74 insertions(+), 11069 deletions(-) create mode 100644 composer.lock rename vendor/{lusitanian/oauth => composer}/LICENSE (90%) delete mode 100644 vendor/lusitanian/oauth/.gitignore delete mode 100644 vendor/lusitanian/oauth/.scrutinizer.yml delete mode 100644 vendor/lusitanian/oauth/.travis.yml delete mode 100644 vendor/lusitanian/oauth/README.md delete mode 100644 vendor/lusitanian/oauth/composer.json delete mode 100644 vendor/lusitanian/oauth/composer.lock delete mode 100644 vendor/lusitanian/oauth/phpunit.xml.dist delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/AutoLoader.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Consumer/Credentials.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Consumer/CredentialsInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Exception/Exception.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/AbstractClient.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/ClientInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/CurlClient.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/StreamClient.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Exception/TokenResponseException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/Uri.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactory.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactoryInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Service/AbstractService.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Service/ServiceInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/AuthorizationStateNotFoundException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/StorageException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/Exception/TokenNotFoundException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/Memory.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/Session.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/SymfonySession.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Storage/TokenStorageInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Token/AbstractToken.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Token/Exception/ExpiredTokenException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/Common/Token/TokenInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/AbstractService.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/BitBucket.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Etsy.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FitBit.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FiveHundredPx.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Flickr.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/QuickBooks.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Redmine.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ScoopIt.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ServiceInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Tumblr.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Twitter.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Xing.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Yahoo.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Signature.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/SignatureInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/StdOAuth1Token.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/TokenInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/AbstractService.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Amazon.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitly.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitrix24.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Box.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Buffer.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dailymotion.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Deezer.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Delicious.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/DeviantArt.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dropbox.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/EveOnline.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAuthorizationStateException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidScopeException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Facebook.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Foursquare.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/GitHub.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Google.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Harvest.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Heroku.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Hubic.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Instagram.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/JawboneUP.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Linkedin.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Mailchimp.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Microsoft.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Nest.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Netatmo.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ParrotFlowerPower.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Paypal.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pinterest.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pocket.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Reddit.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/RunKeeper.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Salesforce.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ServiceInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/SoundCloud.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Spotify.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Strava.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Ustream.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vimeo.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vkontakte.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yahoo.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yammer.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/StdOAuth2Token.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/TokenInterface.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/ServiceFactory.php delete mode 100644 vendor/lusitanian/oauth/src/OAuth/bootstrap.php diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..b4eee9e --- /dev/null +++ b/composer.lock @@ -0,0 +1,63 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "468b7385e7f02c35396a205864c36ceb", + "content-hash": "540c2e320c9819de1b7c90b59f17263d", + "packages": [ + { + "name": "birke/rememberme", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/gbirke/rememberme.git", + "reference": "4e71b0d9c692db28ae78c7eea752c4599b87dc2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/gbirke/rememberme/zipball/4e71b0d9c692db28ae78c7eea752c4599b87dc2c", + "reference": "4e71b0d9c692db28ae78c7eea752c4599b87dc2c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Birke\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gabriel Birke", + "email": "gb@birke-software.de" + } + ], + "description": "Secure \"Remember Me\" functionality", + "homepage": "https://github.com/gbirke/rememberme", + "keywords": [ + "cookie", + "remember", + "security" + ], + "time": "2015-07-22 18:26:14" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4.0" + }, + "platform-dev": [] +} diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 4e05d3b..ff6ecfb 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -13,9 +13,7 @@ namespace Composer\Autoload; /** - * ClassLoader implements a PSR-0 class loader - * - * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. * * $loader = new \Composer\Autoload\ClassLoader(); * @@ -39,6 +37,8 @@ * * @author Fabien Potencier * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ */ class ClassLoader { @@ -147,7 +147,7 @@ public function add($prefix, $paths, $prepend = false) * appending or prepending to the ones previously set for this namespace. * * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-0 base directories + * @param array|string $paths The PSR-4 base directories * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException @@ -351,7 +351,7 @@ private function findFileWithExtension($class, $ext) foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { if (0 === strpos($class, $prefix)) { foreach ($this->prefixDirsPsr4[$prefix] as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { return $file; } } @@ -361,7 +361,7 @@ private function findFileWithExtension($class, $ext) // PSR-4 fallback dirs foreach ($this->fallbackDirsPsr4 as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { return $file; } } @@ -380,7 +380,7 @@ private function findFileWithExtension($class, $ext) foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { if (0 === strpos($class, $prefix)) { foreach ($dirs as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { return $file; } } @@ -390,7 +390,7 @@ private function findFileWithExtension($class, $ext) // PSR-0 fallback dirs foreach ($this->fallbackDirsPsr0 as $dir) { - if (is_file($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { return $file; } } diff --git a/vendor/lusitanian/oauth/LICENSE b/vendor/composer/LICENSE similarity index 90% rename from vendor/lusitanian/oauth/LICENSE rename to vendor/composer/LICENSE index cea529b..c8d57af 100644 --- a/vendor/lusitanian/oauth/LICENSE +++ b/vendor/composer/LICENSE @@ -1,5 +1,5 @@ -(c) 2013 David Desberg -Contributions (c) 2013 Pieter Hordijk + +Copyright (c) 2015 Nils Adermann, Jordi Boggiano Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,3 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index 95c4f01..b7fc012 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -6,6 +6,4 @@ $baseDir = dirname($vendorDir); return array( - 'OAuth\\Unit' => array($vendorDir . '/lusitanian/oauth/tests'), - 'OAuth' => array($vendorDir . '/lusitanian/oauth/src'), ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index a690f0e..a39a2c9 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -43,8 +43,3 @@ public static function getLoader() return $loader; } } - -function composerRequire71f652402b8b0a33907795a253fefcfe($file) -{ - require $file; -} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 907d98c..ee87703 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -42,74 +42,5 @@ "remember", "security" ] - }, - { - "name": "lusitanian/oauth", - "version": "v0.8.3", - "version_normalized": "0.8.3.0", - "source": { - "type": "git", - "url": "https://github.com/Lusitanian/PHPoAuthLib.git", - "reference": "d47849e3838a7ea738111e3f1d7c810cc950539a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/d47849e3838a7ea738111e3f1d7c810cc950539a", - "reference": "d47849e3838a7ea738111e3f1d7c810cc950539a", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*", - "predis/predis": "0.8.*@dev", - "squizlabs/php_codesniffer": "2.*", - "symfony/http-foundation": "~2.1" - }, - "suggest": { - "ext-openssl": "Allows for usage of secure connections with the stream-based HTTP client.", - "predis/predis": "Allows using the Redis storage backend.", - "symfony/http-foundation": "Allows using the Symfony Session storage backend." - }, - "time": "2015-11-17 21:54:31", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "OAuth": "src", - "OAuth\\Unit": "tests" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "David Desberg", - "email": "david@daviddesberg.com" - }, - { - "name": "Elliot Chance", - "email": "elliotchance@gmail.com" - }, - { - "name": "Pieter Hordijk", - "email": "info@pieterhordijk.com" - } - ], - "description": "PHP 5.3+ oAuth 1/2 Library", - "keywords": [ - "Authentication", - "authorization", - "oauth", - "security" - ] } ] diff --git a/vendor/lusitanian/oauth/.gitignore b/vendor/lusitanian/oauth/.gitignore deleted file mode 100644 index 54a7fcf..0000000 --- a/vendor/lusitanian/oauth/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.idea -vendor -.DS_Store -examples/init.php -atlassian-ide-plugin.xml -nbproject/ diff --git a/vendor/lusitanian/oauth/.scrutinizer.yml b/vendor/lusitanian/oauth/.scrutinizer.yml deleted file mode 100644 index 5a274c9..0000000 --- a/vendor/lusitanian/oauth/.scrutinizer.yml +++ /dev/null @@ -1,37 +0,0 @@ -before_commands: - - "composer install --dev --prefer-source" - -tools: - php_code_coverage: - enabled: true - test_command: phpunit -c phpunit.xml.dist - filter: - paths: ["src/*"] - php_code_sniffer: - enabled: true - config: - standard: PSR2 - filter: - paths: ["src/*"] - php_cpd: - enabled: true - excluded_dirs: ["examples", "tests", "vendor"] - php_cs_fixer: - enabled: true - config: - level: all - filter: - paths: ["src/*", "tests/*"] - php_loc: - enabled: true - php_mess_detector: - enabled: true - filter: - paths: ["src/*"] - php_pdepend: - enabled: true - excluded_dirs: ["tests", "examples", "vendor"] - php_analyzer: - filter: - paths: ["src/*", "tests/*"] - sensiolabs_security_checker: true diff --git a/vendor/lusitanian/oauth/.travis.yml b/vendor/lusitanian/oauth/.travis.yml deleted file mode 100644 index d279937..0000000 --- a/vendor/lusitanian/oauth/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -sudo: false -language: php - -php: - - 5.3 - - 5.4 - - 5.5 - - 5.6 - - hhvm - -matrix: - allow_failures: - - php: hhvm - -before_script: - - composer self-update - - composer install - - phpenv rehash - -script: - - phpunit --coverage-text diff --git a/vendor/lusitanian/oauth/README.md b/vendor/lusitanian/oauth/README.md deleted file mode 100644 index 0733056..0000000 --- a/vendor/lusitanian/oauth/README.md +++ /dev/null @@ -1,123 +0,0 @@ -PHPoAuthLib -=========== -**NOTE: I'm looking for someone who could help to maintain this package alongside me, just because I don't have a ton of time to devote to it. However, I'm still going to keep trying to pay attention to PRs, etc.** - -PHPoAuthLib provides oAuth support in PHP 5.3+ and is very easy to integrate with any project which requires an oAuth client. - -[![Build Status](https://travis-ci.org/Lusitanian/PHPoAuthLib.png?branch=master)](https://travis-ci.org/Lusitanian/PHPoAuthLib) -[![Code Coverage](https://scrutinizer-ci.com/g/Lusitanian/PHPoAuthLib/badges/coverage.png?s=a0a15bebfda49e79f9ce289b00c6dfebd18fc98e)](https://scrutinizer-ci.com/g/Lusitanian/PHPoAuthLib/) -[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/Lusitanian/PHPoAuthLib/badges/quality-score.png?s=c5976d2fefceb501f0d886c1a5bf087e69b44533)](https://scrutinizer-ci.com/g/Lusitanian/PHPoAuthLib/) -[![Latest Stable Version](https://poser.pugx.org/lusitanian/oauth/v/stable.png)](https://packagist.org/packages/lusitanian/oauth) -[![Total Downloads](https://poser.pugx.org/lusitanian/oauth/downloads.png)](https://packagist.org/packages/lusitanian/oauth) - -Installation ------------- -This library can be found on [Packagist](https://packagist.org/packages/lusitanian/oauth). -The recommended way to install this is through [composer](http://getcomposer.org). - -Edit your `composer.json` and add: - -```json -{ - "require": { - "lusitanian/oauth": "~0.3" - } -} -``` - -And install dependencies: - -```bash -$ curl -sS https://getcomposer.org/installer | php -$ php composer.phar install -``` - -Features --------- -- PSR-0 compliant for easy interoperability -- Fully extensible in every facet. - - You can implement any service with any custom requirements by extending the protocol version's `AbstractService` implementation. - - You can use any HTTP client you desire, just create a class utilizing it which implements `OAuth\Common\Http\ClientInterface` (two implementations are included) - - You can use any storage mechanism for tokens. By default, session, in-memory and Redis.io (requires PHPRedis) storage mechanisms are included. Implement additional mechanisms by implementing `OAuth\Common\Token\TokenStorageInterface`. - -Service support ---------------- -The library supports both oAuth 1.x and oAuth 2.0 compliant services. A list of currently implemented services can be found below. - -Included service implementations --------------------------------- -- OAuth1 - - 500px - - BitBucket - - Etsy - - FitBit - - Flickr - - QuickBooks - - Scoop.it! - - Tumblr - - Twitter - - Xing - - Yahoo -- OAuth2 - - Amazon - - BitLy - - Bitrix24 - - Box - - Buffer - - Dailymotion - - Delicious - - Deezer - - DeviantArt - - Dropbox - - Eve Online - - Facebook - - Foursquare - - GitHub - - Google - - Harvest - - Heroku - - Hubic - - Instagram - - Jawbone UP - - LinkedIn - - Mailchimp - - Microsoft - - Nest - - Netatmo - - Parrot Flower Power - - PayPal - - Pinterest - - Pocket - - Reddit - - RunKeeper - - Salesforce - - SoundCloud - - Spotify - - Strava - - Ustream - - Vimeo - - Vkontakte - - Yahoo - - Yammer -- more to come! - -Examples --------- -Examples of basic usage are located in the examples/ directory. - -Usage ------- -For usage with complete auth flow, please see the examples. More in-depth documentation will come with release 1.0. - -Framework Integration ---------------------- -* Lithium: Sébastien Charrier has written [an adapter](https://github.com/scharrier/li3_socialauth) for the library. -* Laravel 4: Dariusz Prząda has written [a service provider](https://github.com/artdarek/oauth-4-laravel) for the library. - -Extensions ----------- -* Extract normalized user data from OAuth Services with the library [PHPoAuthUserData](https://github.com/Oryzone/PHPoAuthUserData) by Luciano Mammino - -Tests ------- -To run the tests, you must install dependencies with `composer install --dev` diff --git a/vendor/lusitanian/oauth/composer.json b/vendor/lusitanian/oauth/composer.json deleted file mode 100644 index 66fc46a..0000000 --- a/vendor/lusitanian/oauth/composer.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "lusitanian/oauth", - "description": "PHP 5.3+ oAuth 1/2 Library", - "keywords": ["oauth", "authentication", "authorization", "security"], - "license": "MIT", - "authors": [ - { - "name": "David Desberg", - "email": "david@daviddesberg.com" - }, - { - "name": "Pieter Hordijk", - "email": "info@pieterhordijk.com" - }, - { - "name": "Elliot Chance", - "email": "elliotchance@gmail.com" - } - ], - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "symfony/http-foundation": "~2.1", - "predis/predis": "0.8.*@dev", - "phpunit/phpunit": "3.7.*", - "squizlabs/php_codesniffer": "2.*" - }, - "suggest": { - "symfony/http-foundation": "Allows using the Symfony Session storage backend.", - "predis/predis": "Allows using the Redis storage backend.", - "ext-openssl": "Allows for usage of secure connections with the stream-based HTTP client." - }, - "autoload": { - "psr-0": { - "OAuth": "src", - "OAuth\\Unit": "tests" - } - }, - "extra": { - "branch-alias": { - "dev-master": "0.1-dev" - } - } -} diff --git a/vendor/lusitanian/oauth/composer.lock b/vendor/lusitanian/oauth/composer.lock deleted file mode 100644 index 42ceafe..0000000 --- a/vendor/lusitanian/oauth/composer.lock +++ /dev/null @@ -1,610 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "734ee27aca2b4b8a33857520f518ef0c", - "packages": [], - "packages-dev": [ - { - "name": "phpunit/php-code-coverage", - "version": "1.2.18", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", - "reference": "fe2466802556d3fe4e4d1d58ffd3ccfd0a19be0b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": ">=1.3.0@stable", - "phpunit/php-text-template": ">=1.2.0@stable", - "phpunit/php-token-stream": ">=1.1.3,<1.3.0" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*@dev" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.0.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2014-09-02 10:13:14" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2015-06-21 13:08:43" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21 13:50:34" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2015-06-21 08:01:12" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2014-03-03 05:10:30" - }, - { - "name": "phpunit/phpunit", - "version": "3.7.38", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/38709dc22d519a3d1be46849868aa2ddf822bcf6", - "reference": "38709dc22d519a3d1be46849868aa2ddf822bcf6", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpunit/php-code-coverage": "~1.2", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.1", - "phpunit/php-timer": "~1.0", - "phpunit/phpunit-mock-objects": "~1.2", - "symfony/yaml": "~2.0" - }, - "require-dev": { - "pear-pear.php.net/pear": "1.9.4" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "composer/bin/phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.7.x-dev" - } - }, - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2014-10-17 09:04:17" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "1.2.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5794e3c5c5ba0fb037b11d8151add2a07fa82875", - "reference": "5794e3c5c5ba0fb037b11d8151add2a07fa82875", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": ">=1.1.1@stable" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2013-01-13 10:24:48" - }, - { - "name": "predis/predis", - "version": "0.8.x-dev", - "source": { - "type": "git", - "url": "https://github.com/nrk/predis.git", - "reference": "192dfd61e54c3d32c9526bba03365fff818e17e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nrk/predis/zipball/192dfd61e54c3d32c9526bba03365fff818e17e4", - "reference": "192dfd61e54c3d32c9526bba03365fff818e17e4", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "ext-curl": "Allows access to Webdis when paired with phpiredis", - "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" - }, - "type": "library", - "autoload": { - "psr-0": { - "Predis": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniele Alessandri", - "email": "suppakilla@gmail.com", - "homepage": "http://clorophilla.net" - } - ], - "description": "Flexible and feature-complete PHP client library for Redis", - "homepage": "http://github.com/nrk/predis", - "keywords": [ - "nosql", - "predis", - "redis" - ], - "time": "2015-07-07 17:11:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "2.3.4", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "11a2545c44a5915f883e2e5ec12e14ed345e3ab2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/11a2545c44a5915f883e2e5ec12e14ed345e3ab2", - "reference": "11a2545c44a5915f883e2e5ec12e14ed345e3ab2", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.1.2" - }, - "bin": [ - "scripts/phpcs", - "scripts/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Fixer.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2015-09-09 00:18:50" - }, - { - "name": "symfony/http-foundation", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "7253c2041652353e71560bbd300d6256d170ddaf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/7253c2041652353e71560bbd300d6256d170ddaf", - "reference": "7253c2041652353e71560bbd300d6256d170ddaf", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/expression-language": "~2.4", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony HttpFoundation Component", - "homepage": "https://symfony.com", - "time": "2015-08-27 06:45:45" - }, - { - "name": "symfony/yaml", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/2dc7b06c065df96cc686c66da2705e5e18aef661", - "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "time": "2015-08-24 07:13:45" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "predis/predis": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.3.0" - }, - "platform-dev": [] -} diff --git a/vendor/lusitanian/oauth/phpunit.xml.dist b/vendor/lusitanian/oauth/phpunit.xml.dist deleted file mode 100644 index ee28195..0000000 --- a/vendor/lusitanian/oauth/phpunit.xml.dist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - tests/Unit - - - - - src/ - - src/OAuth/bootstrap.php - src/OAuth/Common/Exception/Exception.php - src/OAuth/Common/Http/Exception/TokenResponseException.php - src/OAuth/Common/Storage/Exception/StorageException.php - src/OAuth/Common/Storage/Exception/TokenNotFoundException.php - src/OAuth/Common/Token/Exception/ExpiredTokenException.php - src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php - src/OAuth/OAuth2/Service/Exception/InvalidScopeException.php - src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php - src/OAuth/OAuth2/Token/StdOAuth2Token.php - - - - - - - - diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/AutoLoader.php b/vendor/lusitanian/oauth/src/OAuth/Common/AutoLoader.php deleted file mode 100644 index 9fe7951..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/AutoLoader.php +++ /dev/null @@ -1,81 +0,0 @@ - - */ -class AutoLoader -{ - /** - * @var string The namespace prefix for this instance. - */ - protected $namespace = ''; - - /** - * @var string The filesystem prefix to use for this instance - */ - protected $path = ''; - - /** - * Build the instance of the autoloader - * - * @param string $namespace The prefixed namespace this instance will load - * @param string $path The filesystem path to the root of the namespace - */ - public function __construct($namespace, $path) - { - $this->namespace = ltrim($namespace, '\\'); - $this->path = rtrim($path, '/\\') . DIRECTORY_SEPARATOR; - } - - /** - * Try to load a class - * - * @param string $class The class name to load - * - * @return boolean If the loading was successful - */ - public function load($class) - { - $class = ltrim($class, '\\'); - - if (strpos($class, $this->namespace) === 0) { - $nsparts = explode('\\', $class); - $class = array_pop($nsparts); - $nsparts[] = ''; - $path = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts); - $path .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; - - if (file_exists($path)) { - require $path; - - return true; - } - } - - return false; - } - - /** - * Register the autoloader to PHP - * - * @return boolean The status of the registration - */ - public function register() - { - return spl_autoload_register(array($this, 'load')); - } - - /** - * Unregister the autoloader to PHP - * - * @return boolean The status of the unregistration - */ - public function unregister() - { - return spl_autoload_unregister(array($this, 'load')); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/Credentials.php b/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/Credentials.php deleted file mode 100644 index 8e98e9f..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/Credentials.php +++ /dev/null @@ -1,60 +0,0 @@ -consumerId = $consumerId; - $this->consumerSecret = $consumerSecret; - $this->callbackUrl = $callbackUrl; - } - - /** - * @return string - */ - public function getCallbackUrl() - { - return $this->callbackUrl; - } - - /** - * @return string - */ - public function getConsumerId() - { - return $this->consumerId; - } - - /** - * @return string - */ - public function getConsumerSecret() - { - return $this->consumerSecret; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/CredentialsInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/CredentialsInterface.php deleted file mode 100644 index a33e54e..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Consumer/CredentialsInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -userAgent = $userAgent; - } - - /** - * @param int $redirects Maximum redirects for client - * - * @return ClientInterface - */ - public function setMaxRedirects($redirects) - { - $this->maxRedirects = $redirects; - - return $this; - } - - /** - * @param int $timeout Request timeout time for client in seconds - * - * @return ClientInterface - */ - public function setTimeout($timeout) - { - $this->timeout = $timeout; - - return $this; - } - - /** - * @param array $headers - */ - public function normalizeHeaders(&$headers) - { - // Normalize headers - array_walk( - $headers, - function (&$val, &$key) { - $key = ucfirst(strtolower($key)); - $val = ucfirst(strtolower($key)) . ': ' . $val; - } - ); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/ClientInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/ClientInterface.php deleted file mode 100644 index f9c2022..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/ClientInterface.php +++ /dev/null @@ -1,32 +0,0 @@ - value` pairs) to be passed to `curl_setopt` - * - * @var array - */ - private $parameters = array(); - - /** - * Additional `curl_setopt` parameters - * - * @param array $parameters - */ - public function setCurlParameters(array $parameters) - { - $this->parameters = $parameters; - } - - /** - * @param bool $force - * - * @return CurlClient - */ - public function setForceSSL3($force) - { - $this->forceSSL3 = $force; - - return $this; - } - - /** - * Any implementing HTTP providers should send a request to the provided endpoint with the parameters. - * They should return, in string form, the response body and throw an exception on error. - * - * @param UriInterface $endpoint - * @param mixed $requestBody - * @param array $extraHeaders - * @param string $method - * - * @return string - * - * @throws TokenResponseException - * @throws \InvalidArgumentException - */ - public function retrieveResponse( - UriInterface $endpoint, - $requestBody, - array $extraHeaders = array(), - $method = 'POST' - ) { - // Normalize method name - $method = strtoupper($method); - - $this->normalizeHeaders($extraHeaders); - - if ($method === 'GET' && !empty($requestBody)) { - throw new \InvalidArgumentException('No body expected for "GET" request.'); - } - - if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) { - $extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded'; - } - - $extraHeaders['Host'] = 'Host: '.$endpoint->getHost(); - $extraHeaders['Connection'] = 'Connection: close'; - - $ch = curl_init(); - - curl_setopt($ch, CURLOPT_URL, $endpoint->getAbsoluteUri()); - - if ($method === 'POST' || $method === 'PUT') { - if ($requestBody && is_array($requestBody)) { - $requestBody = http_build_query($requestBody, '', '&'); - } - - if ($method === 'PUT') { - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); - } else { - curl_setopt($ch, CURLOPT_POST, true); - } - - curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody); - } else { - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); - } - - if ($this->maxRedirects > 0) { - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_MAXREDIRS, $this->maxRedirects); - } - - curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HEADER, false); - curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders); - curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent); - - foreach ($this->parameters as $key => $value) { - curl_setopt($ch, $key, $value); - } - - if ($this->forceSSL3) { - curl_setopt($ch, CURLOPT_SSLVERSION, 3); - } - - $response = curl_exec($ch); - $responseCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - - if (false === $response) { - $errNo = curl_errno($ch); - $errStr = curl_error($ch); - curl_close($ch); - if (empty($errStr)) { - throw new TokenResponseException('Failed to request resource.', $responseCode); - } - throw new TokenResponseException('cURL Error # '.$errNo.': '.$errStr, $responseCode); - } - - curl_close($ch); - - return $response; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/StreamClient.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/StreamClient.php deleted file mode 100644 index d81fee8..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Client/StreamClient.php +++ /dev/null @@ -1,95 +0,0 @@ -normalizeHeaders($extraHeaders); - - if ($method === 'GET' && !empty($requestBody)) { - throw new \InvalidArgumentException('No body expected for "GET" request.'); - } - - if (!isset($extraHeaders['Content-Type']) && $method === 'POST' && is_array($requestBody)) { - $extraHeaders['Content-Type'] = 'Content-Type: application/x-www-form-urlencoded'; - } - - $host = 'Host: '.$endpoint->getHost(); - // Append port to Host if it has been specified - if ($endpoint->hasExplicitPortSpecified()) { - $host .= ':'.$endpoint->getPort(); - } - - $extraHeaders['Host'] = $host; - $extraHeaders['Connection'] = 'Connection: close'; - - if (is_array($requestBody)) { - $requestBody = http_build_query($requestBody, '', '&'); - } - $extraHeaders['Content-length'] = 'Content-length: '.strlen($requestBody); - - $context = $this->generateStreamContext($requestBody, $extraHeaders, $method); - - $level = error_reporting(0); - $response = file_get_contents($endpoint->getAbsoluteUri(), false, $context); - error_reporting($level); - if (false === $response) { - $lastError = error_get_last(); - if (is_null($lastError)) { - throw new TokenResponseException( - 'Failed to request resource. HTTP Code: ' . - ((isset($http_response_header[0]))?$http_response_header[0]:'No response') - ); - } - throw new TokenResponseException($lastError['message']); - } - - return $response; - } - - private function generateStreamContext($body, $headers, $method) - { - return stream_context_create( - array( - 'http' => array( - 'method' => $method, - 'header' => implode("\r\n", array_values($headers)), - 'content' => $body, - 'protocol_version' => '1.1', - 'user_agent' => $this->userAgent, - 'max_redirects' => $this->maxRedirects, - 'timeout' => $this->timeout - ), - ) - ); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Exception/TokenResponseException.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Exception/TokenResponseException.php deleted file mode 100644 index c519a22..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Exception/TokenResponseException.php +++ /dev/null @@ -1,12 +0,0 @@ -parseUri($uri); - } - } - - /** - * @param string $uri - * - * @throws \InvalidArgumentException - */ - protected function parseUri($uri) - { - if (false === ($uriParts = parse_url($uri))) { - // congratulations if you've managed to get parse_url to fail, - // it seems to always return some semblance of a parsed url no matter what - throw new InvalidArgumentException("Invalid URI: $uri"); - } - - if (!isset($uriParts['scheme'])) { - throw new InvalidArgumentException('Invalid URI: http|https scheme required'); - } - - $this->scheme = $uriParts['scheme']; - $this->host = $uriParts['host']; - - if (isset($uriParts['port'])) { - $this->port = $uriParts['port']; - $this->explicitPortSpecified = true; - } else { - $this->port = strcmp('https', $uriParts['scheme']) ? 80 : 443; - $this->explicitPortSpecified = false; - } - - if (isset($uriParts['path'])) { - $this->path = $uriParts['path']; - if ('/' === $uriParts['path']) { - $this->explicitTrailingHostSlash = true; - } - } else { - $this->path = '/'; - } - - $this->query = isset($uriParts['query']) ? $uriParts['query'] : ''; - $this->fragment = isset($uriParts['fragment']) ? $uriParts['fragment'] : ''; - - $userInfo = ''; - if (!empty($uriParts['user'])) { - $userInfo .= $uriParts['user']; - } - if ($userInfo && !empty($uriParts['pass'])) { - $userInfo .= ':' . $uriParts['pass']; - } - - $this->setUserInfo($userInfo); - } - - /** - * @param string $rawUserInfo - * - * @return string - */ - protected function protectUserInfo($rawUserInfo) - { - $colonPos = strpos($rawUserInfo, ':'); - - // rfc3986-3.2.1 | http://tools.ietf.org/html/rfc3986#section-3.2 - // "Applications should not render as clear text any data - // after the first colon (":") character found within a userinfo - // subcomponent unless the data after the colon is the empty string - // (indicating no password)" - if ($colonPos !== false && strlen($rawUserInfo)-1 > $colonPos) { - return substr($rawUserInfo, 0, $colonPos) . ':********'; - } else { - return $rawUserInfo; - } - } - - /** - * @return string - */ - public function getScheme() - { - return $this->scheme; - } - - /** - * @return string - */ - public function getUserInfo() - { - return $this->userInfo; - } - - /** - * @return string - */ - public function getRawUserInfo() - { - return $this->rawUserInfo; - } - - /** - * @return string - */ - public function getHost() - { - return $this->host; - } - - /** - * @return int - */ - public function getPort() - { - return $this->port; - } - - /** - * @return string - */ - public function getPath() - { - return $this->path; - } - - /** - * @return string - */ - public function getQuery() - { - return $this->query; - } - - /** - * @return string - */ - public function getFragment() - { - return $this->fragment; - } - - /** - * Uses protected user info by default as per rfc3986-3.2.1 - * Uri::getRawAuthority() is available if plain-text password information is desirable. - * - * @return string - */ - public function getAuthority() - { - $authority = $this->userInfo ? $this->userInfo.'@' : ''; - $authority .= $this->host; - - if ($this->explicitPortSpecified) { - $authority .= ":{$this->port}"; - } - - return $authority; - } - - /** - * @return string - */ - public function getRawAuthority() - { - $authority = $this->rawUserInfo ? $this->rawUserInfo.'@' : ''; - $authority .= $this->host; - - if ($this->explicitPortSpecified) { - $authority .= ":{$this->port}"; - } - - return $authority; - } - - /** - * @return string - */ - public function getAbsoluteUri() - { - $uri = $this->scheme . '://' . $this->getRawAuthority(); - - if ('/' === $this->path) { - $uri .= $this->explicitTrailingHostSlash ? '/' : ''; - } else { - $uri .= $this->path; - } - - if (!empty($this->query)) { - $uri .= "?{$this->query}"; - } - - if (!empty($this->fragment)) { - $uri .= "#{$this->fragment}"; - } - - return $uri; - } - - /** - * @return string - */ - public function getRelativeUri() - { - $uri = ''; - - if ('/' === $this->path) { - $uri .= $this->explicitTrailingHostSlash ? '/' : ''; - } else { - $uri .= $this->path; - } - - return $uri; - } - - /** - * Uses protected user info by default as per rfc3986-3.2.1 - * Uri::getAbsoluteUri() is available if plain-text password information is desirable. - * - * @return string - */ - public function __toString() - { - $uri = $this->scheme . '://' . $this->getAuthority(); - - if ('/' === $this->path) { - $uri .= $this->explicitTrailingHostSlash ? '/' : ''; - } else { - $uri .= $this->path; - } - - if (!empty($this->query)) { - $uri .= "?{$this->query}"; - } - - if (!empty($this->fragment)) { - $uri .= "#{$this->fragment}"; - } - - return $uri; - } - - /** - * @param $path - */ - public function setPath($path) - { - if (empty($path)) { - $this->path = '/'; - $this->explicitTrailingHostSlash = false; - } else { - $this->path = $path; - if ('/' === $this->path) { - $this->explicitTrailingHostSlash = true; - } - } - } - - /** - * @param string $query - */ - public function setQuery($query) - { - $this->query = $query; - } - - /** - * @param string $var - * @param string $val - */ - public function addToQuery($var, $val) - { - if (strlen($this->query) > 0) { - $this->query .= '&'; - } - $this->query .= http_build_query(array($var => $val), '', '&'); - } - - /** - * @param string $fragment - */ - public function setFragment($fragment) - { - $this->fragment = $fragment; - } - - /** - * @param string $scheme - */ - public function setScheme($scheme) - { - $this->scheme = $scheme; - } - - - /** - * @param string $userInfo - */ - public function setUserInfo($userInfo) - { - $this->userInfo = $userInfo ? $this->protectUserInfo($userInfo) : ''; - $this->rawUserInfo = $userInfo; - } - - - /** - * @param int $port - */ - public function setPort($port) - { - $this->port = intval($port); - - if (('https' === $this->scheme && $this->port === 443) || ('http' === $this->scheme && $this->port === 80)) { - $this->explicitPortSpecified = false; - } else { - $this->explicitPortSpecified = true; - } - } - - /** - * @param string $host - */ - public function setHost($host) - { - $this->host = $host; - } - - /** - * @return bool - */ - public function hasExplicitTrailingHostSlash() - { - return $this->explicitTrailingHostSlash; - } - - /** - * @return bool - */ - public function hasExplicitPortSpecified() - { - return $this->explicitPortSpecified; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactory.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactory.php deleted file mode 100644 index 127aa20..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactory.php +++ /dev/null @@ -1,168 +0,0 @@ -attemptProxyStyleParse($_server)) { - return $uri; - } - - $scheme = $this->detectScheme($_server); - $host = $this->detectHost($_server); - $port = $this->detectPort($_server); - $path = $this->detectPath($_server); - $query = $this->detectQuery($_server); - - return $this->createFromParts($scheme, '', $host, $port, $path, $query); - } - - /** - * @param string $absoluteUri - * - * @return UriInterface - */ - public function createFromAbsolute($absoluteUri) - { - return new Uri($absoluteUri); - } - - /** - * Factory method to build a URI from parts - * - * @param string $scheme - * @param string $userInfo - * @param string $host - * @param string $port - * @param string $path - * @param string $query - * @param string $fragment - * - * @return UriInterface - */ - public function createFromParts($scheme, $userInfo, $host, $port, $path = '', $query = '', $fragment = '') - { - $uri = new Uri(); - $uri->setScheme($scheme); - $uri->setUserInfo($userInfo); - $uri->setHost($host); - $uri->setPort($port); - $uri->setPath($path); - $uri->setQuery($query); - $uri->setFragment($fragment); - - return $uri; - } - - /** - * @param array $_server - * - * @return UriInterface|null - */ - private function attemptProxyStyleParse($_server) - { - // If the raw HTTP request message arrives with a proxy-style absolute URI in the - // initial request line, the absolute URI is stored in $_SERVER['REQUEST_URI'] and - // we only need to parse that. - if (isset($_server['REQUEST_URI']) && parse_url($_server['REQUEST_URI'], PHP_URL_SCHEME)) { - return new Uri($_server['REQUEST_URI']); - } - - return null; - } - - /** - * @param array $_server - * - * @return string - * - * @throws RuntimeException - */ - private function detectPath($_server) - { - if (isset($_server['REQUEST_URI'])) { - $uri = $_server['REQUEST_URI']; - } elseif (isset($_server['REDIRECT_URL'])) { - $uri = $_server['REDIRECT_URL']; - } else { - throw new RuntimeException('Could not detect URI path from superglobal'); - } - - $queryStr = strpos($uri, '?'); - if ($queryStr !== false) { - $uri = substr($uri, 0, $queryStr); - } - - return $uri; - } - - /** - * @param array $_server - * - * @return string - */ - private function detectHost(array $_server) - { - $host = isset($_server['HTTP_HOST']) ? $_server['HTTP_HOST'] : ''; - - if (strstr($host, ':')) { - $host = parse_url($host, PHP_URL_HOST); - } - - return $host; - } - - /** - * @param array $_server - * - * @return string - */ - private function detectPort(array $_server) - { - return isset($_server['SERVER_PORT']) ? $_server['SERVER_PORT'] : 80; - } - - /** - * @param array $_server - * - * @return string - */ - private function detectQuery(array $_server) - { - return isset($_server['QUERY_STRING']) ? $_server['QUERY_STRING'] : ''; - } - - /** - * Determine URI scheme component from superglobal array - * - * When using ISAPI with IIS, the value will be "off" if the request was - * not made through the HTTPS protocol. As a result, we filter the - * value to a bool. - * - * @param array $_server A super-global $_SERVER array - * - * @return string Returns http or https depending on the URI scheme - */ - private function detectScheme(array $_server) - { - if (isset($_server['HTTPS']) && filter_var($_server['HTTPS'], FILTER_VALIDATE_BOOLEAN)) { - return 'https'; - } else { - return 'http'; - } - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactoryInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactoryInterface.php deleted file mode 100644 index 2b157d8..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Http/Uri/UriFactoryInterface.php +++ /dev/null @@ -1,42 +0,0 @@ -credentials = $credentials; - $this->httpClient = $httpClient; - $this->storage = $storage; - } - - /** - * @param UriInterface|string $path - * @param UriInterface $baseApiUri - * - * @return UriInterface - * - * @throws Exception - */ - protected function determineRequestUriFromPath($path, UriInterface $baseApiUri = null) - { - if ($path instanceof UriInterface) { - $uri = $path; - } elseif (stripos($path, 'http://') === 0 || stripos($path, 'https://') === 0) { - $uri = new Uri($path); - } else { - if (null === $baseApiUri) { - throw new Exception( - 'An absolute URI must be passed to ServiceInterface::request as no baseApiUri is set.' - ); - } - - $uri = clone $baseApiUri; - if (false !== strpos($path, '?')) { - $parts = explode('?', $path, 2); - $path = $parts[0]; - $query = $parts[1]; - $uri->setQuery($query); - } - - if ($path[0] === '/') { - $path = substr($path, 1); - } - - $uri->setPath($uri->getPath() . $path); - } - - return $uri; - } - - /** - * Accessor to the storage adapter to be able to retrieve tokens - * - * @return TokenStorageInterface - */ - public function getStorage() - { - return $this->storage; - } - - /** - * @return string - */ - public function service() - { - // get class name without backslashes - $classname = get_class($this); - - return preg_replace('/^.*\\\\/', '', $classname); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Service/ServiceInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Service/ServiceInterface.php deleted file mode 100644 index 5856a03..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Service/ServiceInterface.php +++ /dev/null @@ -1,49 +0,0 @@ -tokens = array(); - $this->states = array(); - } - - /** - * {@inheritDoc} - */ - public function retrieveAccessToken($service) - { - if ($this->hasAccessToken($service)) { - return $this->tokens[$service]; - } - - throw new TokenNotFoundException('Token not stored'); - } - - /** - * {@inheritDoc} - */ - public function storeAccessToken($service, TokenInterface $token) - { - $this->tokens[$service] = $token; - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAccessToken($service) - { - return isset($this->tokens[$service]) && $this->tokens[$service] instanceof TokenInterface; - } - - /** - * {@inheritDoc} - */ - public function clearToken($service) - { - if (array_key_exists($service, $this->tokens)) { - unset($this->tokens[$service]); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllTokens() - { - $this->tokens = array(); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function retrieveAuthorizationState($service) - { - if ($this->hasAuthorizationState($service)) { - return $this->states[$service]; - } - - throw new AuthorizationStateNotFoundException('State not stored'); - } - - /** - * {@inheritDoc} - */ - public function storeAuthorizationState($service, $state) - { - $this->states[$service] = $state; - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAuthorizationState($service) - { - return isset($this->states[$service]) && null !== $this->states[$service]; - } - - /** - * {@inheritDoc} - */ - public function clearAuthorizationState($service) - { - if (array_key_exists($service, $this->states)) { - unset($this->states[$service]); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllAuthorizationStates() - { - $this->states = array(); - - // allow chaining - return $this; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php deleted file mode 100644 index 5d3d9ae..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Redis.php +++ /dev/null @@ -1,230 +0,0 @@ -redis = $redis; - $this->key = $key; - $this->stateKey = $stateKey; - $this->cachedTokens = array(); - $this->cachedStates = array(); - } - - /** - * {@inheritDoc} - */ - public function retrieveAccessToken($service) - { - if (!$this->hasAccessToken($service)) { - throw new TokenNotFoundException('Token not found in redis'); - } - - if (isset($this->cachedTokens[$service])) { - return $this->cachedTokens[$service]; - } - - $val = $this->redis->hget($this->key, $service); - - return $this->cachedTokens[$service] = unserialize($val); - } - - /** - * {@inheritDoc} - */ - public function storeAccessToken($service, TokenInterface $token) - { - // (over)write the token - $this->redis->hset($this->key, $service, serialize($token)); - $this->cachedTokens[$service] = $token; - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAccessToken($service) - { - if (isset($this->cachedTokens[$service]) - && $this->cachedTokens[$service] instanceof TokenInterface - ) { - return true; - } - - return $this->redis->hexists($this->key, $service); - } - - /** - * {@inheritDoc} - */ - public function clearToken($service) - { - $this->redis->hdel($this->key, $service); - unset($this->cachedTokens[$service]); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllTokens() - { - // memory - $this->cachedTokens = array(); - - // redis - $keys = $this->redis->hkeys($this->key); - $me = $this; // 5.3 compat - - // pipeline for performance - $this->redis->pipeline( - function ($pipe) use ($keys, $me) { - foreach ($keys as $k) { - $pipe->hdel($me->getKey(), $k); - } - } - ); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function retrieveAuthorizationState($service) - { - if (!$this->hasAuthorizationState($service)) { - throw new AuthorizationStateNotFoundException('State not found in redis'); - } - - if (isset($this->cachedStates[$service])) { - return $this->cachedStates[$service]; - } - - $val = $this->redis->hget($this->stateKey, $service); - - return $this->cachedStates[$service] = $val; - } - - /** - * {@inheritDoc} - */ - public function storeAuthorizationState($service, $state) - { - // (over)write the token - $this->redis->hset($this->stateKey, $service, $state); - $this->cachedStates[$service] = $state; - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAuthorizationState($service) - { - if (isset($this->cachedStates[$service]) - && null !== $this->cachedStates[$service] - ) { - return true; - } - - return $this->redis->hexists($this->stateKey, $service); - } - - /** - * {@inheritDoc} - */ - public function clearAuthorizationState($service) - { - $this->redis->hdel($this->stateKey, $service); - unset($this->cachedStates[$service]); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllAuthorizationStates() - { - // memory - $this->cachedStates = array(); - - // redis - $keys = $this->redis->hkeys($this->stateKey); - $me = $this; // 5.3 compat - - // pipeline for performance - $this->redis->pipeline( - function ($pipe) use ($keys, $me) { - foreach ($keys as $k) { - $pipe->hdel($me->getKey(), $k); - } - } - ); - - // allow chaining - return $this; - } - - /** - * @return Predis $redis - */ - public function getRedis() - { - return $this->redis; - } - - /** - * @return string $key - */ - public function getKey() - { - return $this->key; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Session.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Session.php deleted file mode 100644 index dd9aba7..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/Session.php +++ /dev/null @@ -1,204 +0,0 @@ -sessionHasStarted()) { - session_start(); - } - - $this->startSession = $startSession; - $this->sessionVariableName = $sessionVariableName; - $this->stateVariableName = $stateVariableName; - if (!isset($_SESSION[$sessionVariableName])) { - $_SESSION[$sessionVariableName] = array(); - } - if (!isset($_SESSION[$stateVariableName])) { - $_SESSION[$stateVariableName] = array(); - } - } - - /** - * {@inheritDoc} - */ - public function retrieveAccessToken($service) - { - if ($this->hasAccessToken($service)) { - return unserialize($_SESSION[$this->sessionVariableName][$service]); - } - - throw new TokenNotFoundException('Token not found in session, are you sure you stored it?'); - } - - /** - * {@inheritDoc} - */ - public function storeAccessToken($service, TokenInterface $token) - { - $serializedToken = serialize($token); - - if (isset($_SESSION[$this->sessionVariableName]) - && is_array($_SESSION[$this->sessionVariableName]) - ) { - $_SESSION[$this->sessionVariableName][$service] = $serializedToken; - } else { - $_SESSION[$this->sessionVariableName] = array( - $service => $serializedToken, - ); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAccessToken($service) - { - return isset($_SESSION[$this->sessionVariableName], $_SESSION[$this->sessionVariableName][$service]); - } - - /** - * {@inheritDoc} - */ - public function clearToken($service) - { - if (array_key_exists($service, $_SESSION[$this->sessionVariableName])) { - unset($_SESSION[$this->sessionVariableName][$service]); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllTokens() - { - unset($_SESSION[$this->sessionVariableName]); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function storeAuthorizationState($service, $state) - { - if (isset($_SESSION[$this->stateVariableName]) - && is_array($_SESSION[$this->stateVariableName]) - ) { - $_SESSION[$this->stateVariableName][$service] = $state; - } else { - $_SESSION[$this->stateVariableName] = array( - $service => $state, - ); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAuthorizationState($service) - { - return isset($_SESSION[$this->stateVariableName], $_SESSION[$this->stateVariableName][$service]); - } - - /** - * {@inheritDoc} - */ - public function retrieveAuthorizationState($service) - { - if ($this->hasAuthorizationState($service)) { - return $_SESSION[$this->stateVariableName][$service]; - } - - throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?'); - } - - /** - * {@inheritDoc} - */ - public function clearAuthorizationState($service) - { - if (array_key_exists($service, $_SESSION[$this->stateVariableName])) { - unset($_SESSION[$this->stateVariableName][$service]); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllAuthorizationStates() - { - unset($_SESSION[$this->stateVariableName]); - - // allow chaining - return $this; - } - - public function __destruct() - { - if ($this->startSession) { - session_write_close(); - } - } - - /** - * Determine if the session has started. - * @url http://stackoverflow.com/a/18542272/1470961 - * @return bool - */ - protected function sessionHasStarted() - { - // For more modern PHP versions we use a more reliable method. - if (version_compare(PHP_VERSION, '5.4.0') >= 0) { - return session_status() != PHP_SESSION_NONE; - } - - // Below PHP 5.4 we should test for the current session ID. - return session_id() !== ''; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/SymfonySession.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/SymfonySession.php deleted file mode 100644 index 6c5fbf6..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/SymfonySession.php +++ /dev/null @@ -1,200 +0,0 @@ -session = $session; - $this->sessionVariableName = $sessionVariableName; - $this->stateVariableName = $stateVariableName; - } - - /** - * {@inheritDoc} - */ - public function retrieveAccessToken($service) - { - if ($this->hasAccessToken($service)) { - // get from session - $tokens = $this->session->get($this->sessionVariableName); - - // one item - return $tokens[$service]; - } - - throw new TokenNotFoundException('Token not found in session, are you sure you stored it?'); - } - - /** - * {@inheritDoc} - */ - public function storeAccessToken($service, TokenInterface $token) - { - // get previously saved tokens - $tokens = $this->session->get($this->sessionVariableName); - - if (!is_array($tokens)) { - $tokens = array(); - } - - $tokens[$service] = $token; - - // save - $this->session->set($this->sessionVariableName, $tokens); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAccessToken($service) - { - // get from session - $tokens = $this->session->get($this->sessionVariableName); - - return is_array($tokens) - && isset($tokens[$service]) - && $tokens[$service] instanceof TokenInterface; - } - - /** - * {@inheritDoc} - */ - public function clearToken($service) - { - // get previously saved tokens - $tokens = $this->session->get($this->sessionVariableName); - - if (is_array($tokens) && array_key_exists($service, $tokens)) { - unset($tokens[$service]); - - // Replace the stored tokens array - $this->session->set($this->sessionVariableName, $tokens); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllTokens() - { - $this->session->remove($this->sessionVariableName); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function retrieveAuthorizationState($service) - { - if ($this->hasAuthorizationState($service)) { - // get from session - $states = $this->session->get($this->stateVariableName); - - // one item - return $states[$service]; - } - - throw new AuthorizationStateNotFoundException('State not found in session, are you sure you stored it?'); - } - - /** - * {@inheritDoc} - */ - public function storeAuthorizationState($service, $state) - { - // get previously saved tokens - $states = $this->session->get($this->stateVariableName); - - if (!is_array($states)) { - $states = array(); - } - - $states[$service] = $state; - - // save - $this->session->set($this->stateVariableName, $states); - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function hasAuthorizationState($service) - { - // get from session - $states = $this->session->get($this->stateVariableName); - - return is_array($states) - && isset($states[$service]) - && null !== $states[$service]; - } - - /** - * {@inheritDoc} - */ - public function clearAuthorizationState($service) - { - // get previously saved tokens - $states = $this->session->get($this->stateVariableName); - - if (is_array($states) && array_key_exists($service, $states)) { - unset($states[$service]); - - // Replace the stored tokens array - $this->session->set($this->stateVariableName, $states); - } - - // allow chaining - return $this; - } - - /** - * {@inheritDoc} - */ - public function clearAllAuthorizationStates() - { - $this->session->remove($this->stateVariableName); - - // allow chaining - return $this; - } - - /** - * @return Session - */ - public function getSession() - { - return $this->session; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/TokenStorageInterface.php b/vendor/lusitanian/oauth/src/OAuth/Common/Storage/TokenStorageInterface.php deleted file mode 100644 index 46552ce..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Storage/TokenStorageInterface.php +++ /dev/null @@ -1,98 +0,0 @@ -accessToken = $accessToken; - $this->refreshToken = $refreshToken; - $this->setLifetime($lifetime); - $this->extraParams = $extraParams; - } - - /** - * @return string - */ - public function getAccessToken() - { - return $this->accessToken; - } - - /** - * @return string - */ - public function getRefreshToken() - { - return $this->refreshToken; - } - - /** - * @return int - */ - public function getEndOfLife() - { - return $this->endOfLife; - } - - /** - * @param array $extraParams - */ - public function setExtraParams(array $extraParams) - { - $this->extraParams = $extraParams; - } - - /** - * @return array - */ - public function getExtraParams() - { - return $this->extraParams; - } - - /** - * @param string $accessToken - */ - public function setAccessToken($accessToken) - { - $this->accessToken = $accessToken; - } - - /** - * @param int $endOfLife - */ - public function setEndOfLife($endOfLife) - { - $this->endOfLife = $endOfLife; - } - - /** - * @param int $lifetime - */ - public function setLifetime($lifetime) - { - if (0 === $lifetime || static::EOL_NEVER_EXPIRES === $lifetime) { - $this->endOfLife = static::EOL_NEVER_EXPIRES; - } elseif (null !== $lifetime) { - $this->endOfLife = intval($lifetime) + time(); - } else { - $this->endOfLife = static::EOL_UNKNOWN; - } - } - - /** - * @param string $refreshToken - */ - public function setRefreshToken($refreshToken) - { - $this->refreshToken = $refreshToken; - } - - public function isExpired() - { - return ($this->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES - && $this->getEndOfLife() !== TokenInterface::EOL_UNKNOWN - && time() > $this->getEndOfLife()); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/Common/Token/Exception/ExpiredTokenException.php b/vendor/lusitanian/oauth/src/OAuth/Common/Token/Exception/ExpiredTokenException.php deleted file mode 100644 index 26ad6cc..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/Common/Token/Exception/ExpiredTokenException.php +++ /dev/null @@ -1,12 +0,0 @@ -signature = $signature; - $this->baseApiUri = $baseApiUri; - - $this->signature->setHashingAlgorithm($this->getSignatureMethod()); - } - - /** - * {@inheritDoc} - */ - public function requestRequestToken() - { - $authorizationHeader = array('Authorization' => $this->buildAuthorizationHeaderForTokenRequest()); - $headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders()); - - $responseBody = $this->httpClient->retrieveResponse($this->getRequestTokenEndpoint(), array(), $headers); - - $token = $this->parseRequestTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($additionalParameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritDoc} - */ - public function requestAccessToken($token, $verifier, $tokenSecret = null) - { - if (is_null($tokenSecret)) { - $storedRequestToken = $this->storage->retrieveAccessToken($this->service()); - $tokenSecret = $storedRequestToken->getRequestTokenSecret(); - } - $this->signature->setTokenSecret($tokenSecret); - - $bodyParams = array( - 'oauth_verifier' => $verifier, - ); - - $authorizationHeader = array( - 'Authorization' => $this->buildAuthorizationHeaderForAPIRequest( - 'POST', - $this->getAccessTokenEndpoint(), - $this->storage->retrieveAccessToken($this->service()), - $bodyParams - ) - ); - - $headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders()); - - $responseBody = $this->httpClient->retrieveResponse($this->getAccessTokenEndpoint(), $bodyParams, $headers); - - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - /** - * Refreshes an OAuth1 access token - * @param TokenInterface $token - * @return TokenInterface $token - */ - public function refreshAccessToken(TokenInterface $token) - { - } - - /** - * Sends an authenticated API request to the path provided. - * If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used. - * - * @param string|UriInterface $path - * @param string $method HTTP method - * @param array $body Request body if applicable (key/value pairs) - * @param array $extraHeaders Extra headers if applicable. - * These will override service-specific any defaults. - * - * @return string - */ - public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $uri = $this->determineRequestUriFromPath($path, $this->baseApiUri); - - /** @var $token StdOAuth1Token */ - $token = $this->storage->retrieveAccessToken($this->service()); - $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); - $authorizationHeader = array( - 'Authorization' => $this->buildAuthorizationHeaderForAPIRequest($method, $uri, $token, $body) - ); - $headers = array_merge($authorizationHeader, $extraHeaders); - - return $this->httpClient->retrieveResponse($uri, $body, $headers, $method); - } - - /** - * Return any additional headers always needed for this service implementation's OAuth calls. - * - * @return array - */ - protected function getExtraOAuthHeaders() - { - return array(); - } - - /** - * Return any additional headers always needed for this service implementation's API calls. - * - * @return array - */ - protected function getExtraApiHeaders() - { - return array(); - } - - /** - * Builds the authorization header for getting an access or request token. - * - * @param array $extraParameters - * - * @return string - */ - protected function buildAuthorizationHeaderForTokenRequest(array $extraParameters = array()) - { - $parameters = $this->getBasicAuthorizationHeaderInfo(); - $parameters = array_merge($parameters, $extraParameters); - $parameters['oauth_signature'] = $this->signature->getSignature( - $this->getRequestTokenEndpoint(), - $parameters, - 'POST' - ); - - $authorizationHeader = 'OAuth '; - $delimiter = ''; - foreach ($parameters as $key => $value) { - $authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"'; - - $delimiter = ', '; - } - - return $authorizationHeader; - } - - /** - * Builds the authorization header for an authenticated API request - * - * @param string $method - * @param UriInterface $uri The uri the request is headed - * @param TokenInterface $token - * @param array $bodyParams Request body if applicable (key/value pairs) - * - * @return string - */ - protected function buildAuthorizationHeaderForAPIRequest( - $method, - UriInterface $uri, - TokenInterface $token, - $bodyParams = null - ) { - $this->signature->setTokenSecret($token->getAccessTokenSecret()); - $authParameters = $this->getBasicAuthorizationHeaderInfo(); - if (isset($authParameters['oauth_callback'])) { - unset($authParameters['oauth_callback']); - } - - $authParameters = array_merge($authParameters, array('oauth_token' => $token->getAccessToken())); - - $signatureParams = (is_array($bodyParams)) ? array_merge($authParameters, $bodyParams) : $authParameters; - $authParameters['oauth_signature'] = $this->signature->getSignature($uri, $signatureParams, $method); - - if (isset($bodyParams['oauth_session_handle'])) { - $authParameters['oauth_session_handle'] = $bodyParams['oauth_session_handle']; - unset($bodyParams['oauth_session_handle']); - } - - $authorizationHeader = 'OAuth '; - $delimiter = ''; - - foreach ($authParameters as $key => $value) { - $authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"'; - $delimiter = ', '; - } - - return $authorizationHeader; - } - - /** - * Builds the authorization header array. - * - * @return array - */ - protected function getBasicAuthorizationHeaderInfo() - { - $dateTime = new \DateTime(); - $headerParameters = array( - 'oauth_callback' => $this->credentials->getCallbackUrl(), - 'oauth_consumer_key' => $this->credentials->getConsumerId(), - 'oauth_nonce' => $this->generateNonce(), - 'oauth_signature_method' => $this->getSignatureMethod(), - 'oauth_timestamp' => $dateTime->format('U'), - 'oauth_version' => $this->getVersion(), - ); - - return $headerParameters; - } - - /** - * Pseudo random string generator used to build a unique string to sign each request - * - * @param int $length - * - * @return string - */ - protected function generateNonce($length = 32) - { - $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; - - $nonce = ''; - $maxRand = strlen($characters)-1; - for ($i = 0; $i < $length; $i++) { - $nonce.= $characters[rand(0, $maxRand)]; - } - - return $nonce; - } - - /** - * @return string - */ - protected function getSignatureMethod() - { - return 'HMAC-SHA1'; - } - - /** - * This returns the version used in the authorization header of the requests - * - * @return string - */ - protected function getVersion() - { - return '1.0'; - } - - /** - * Parses the request token response and returns a TokenInterface. - * This is only needed to verify the `oauth_callback_confirmed` parameter. The actual - * parsing logic is contained in the access token parser. - * - * @abstract - * - * @param string $responseBody - * - * @return TokenInterface - * - * @throws TokenResponseException - */ - abstract protected function parseRequestTokenResponse($responseBody); - - /** - * Parses the access token response and returns a TokenInterface. - * - * @abstract - * - * @param string $responseBody - * - * @return TokenInterface - * - * @throws TokenResponseException - */ - abstract protected function parseAccessTokenResponse($responseBody); -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/BitBucket.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/BitBucket.php deleted file mode 100644 index f6d8edf..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/BitBucket.php +++ /dev/null @@ -1,96 +0,0 @@ -baseApiUri = new Uri('https://bitbucket.org/api/1.0/'); - } - } - - /** - * {@inheritDoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://bitbucket.org/!api/1.0/oauth/request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://bitbucket.org/!api/1.0/oauth/authenticate'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://bitbucket.org/!api/1.0/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Etsy.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Etsy.php deleted file mode 100644 index 30dc331..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Etsy.php +++ /dev/null @@ -1,132 +0,0 @@ -baseApiUri = new Uri('https://openapi.etsy.com/v2/'); - } - } - - /** - * {@inheritdoc} - */ - public function getRequestTokenEndpoint() - { - $uri = new Uri($this->baseApiUri . 'oauth/request_token'); - $scopes = $this->getScopes(); - - if (count($scopes)) { - $uri->setQuery('scope=' . implode('%20', $scopes)); - } - - return $uri; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri($this->baseApiUri); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri($this->baseApiUri . 'oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } - - /** - * Set the scopes for permissions - * @see https://www.etsy.com/developers/documentation/getting_started/oauth#section_permission_scopes - * @param array $scopes - * - * @return $this - */ - public function setScopes(array $scopes) - { - if (!is_array($scopes)) { - $scopes = array(); - } - - $this->scopes = $scopes; - return $this; - } - - /** - * Return the defined scopes - * @return array - */ - public function getScopes() - { - return $this->scopes; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FitBit.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FitBit.php deleted file mode 100644 index 78032d7..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FitBit.php +++ /dev/null @@ -1,96 +0,0 @@ -baseApiUri = new Uri('https://api.fitbit.com/1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://api.fitbit.com/oauth/request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.fitbit.com/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.fitbit.com/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FiveHundredPx.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FiveHundredPx.php deleted file mode 100644 index ea7f9b3..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/FiveHundredPx.php +++ /dev/null @@ -1,120 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developers.500px.com/ - */ - -namespace OAuth\OAuth1\Service; - -use OAuth\OAuth1\Signature\SignatureInterface; -use OAuth\OAuth1\Token\StdOAuth1Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Uri\UriInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Client\ClientInterface; - -/** - * 500px service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developers.500px.com/ - */ -class FiveHundredPx extends AbstractService -{ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - SignatureInterface $signature, - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $signature, - $baseApiUri - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.500px.com/v1/'); - } - } - - /** - * {@inheritDoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://api.500px.com/v1/oauth/request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.500px.com/v1/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.500px.com/v1/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) - || $data['oauth_callback_confirmed'] !== 'true' - ) { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Flickr.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Flickr.php deleted file mode 100644 index 7ceee7d..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Flickr.php +++ /dev/null @@ -1,133 +0,0 @@ -baseApiUri = new Uri('https://api.flickr.com/services/rest/'); - } - } - - public function getRequestTokenEndpoint() - { - return new Uri('https://www.flickr.com/services/oauth/request_token'); - } - - public function getAuthorizationEndpoint() - { - return new Uri('https://www.flickr.com/services/oauth/authorize'); - } - - public function getAccessTokenEndpoint() - { - return new Uri('https://www.flickr.com/services/oauth/access_token'); - } - - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] != 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - return $this->parseAccessTokenResponse($responseBody); - } - - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - if ($data === null || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } - - public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $uri = $this->determineRequestUriFromPath('/', $this->baseApiUri); - $uri->addToQuery('method', $path); - - if (!empty($this->format)) { - $uri->addToQuery('format', $this->format); - - if ($this->format === 'json') { - $uri->addToQuery('nojsoncallback', 1); - } - } - - $token = $this->storage->retrieveAccessToken($this->service()); - $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); - $authorizationHeader = array( - 'Authorization' => $this->buildAuthorizationHeaderForAPIRequest($method, $uri, $token, $body) - ); - $headers = array_merge($authorizationHeader, $extraHeaders); - - return $this->httpClient->retrieveResponse($uri, $body, $headers, $method); - } - - public function requestRest($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - return $this->request($path, $method, $body, $extraHeaders); - } - - public function requestXmlrpc($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $this->format = 'xmlrpc'; - - return $this->request($path, $method, $body, $extraHeaders); - } - - public function requestSoap($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $this->format = 'soap'; - - return $this->request($path, $method, $body, $extraHeaders); - } - - public function requestJson($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $this->format = 'json'; - - return $this->request($path, $method, $body, $extraHeaders); - } - - public function requestPhp($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $this->format = 'php_serial'; - - return $this->request($path, $method, $body, $extraHeaders); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/QuickBooks.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/QuickBooks.php deleted file mode 100644 index 0014ca8..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/QuickBooks.php +++ /dev/null @@ -1,120 +0,0 @@ -baseApiUri = new Uri('https://quickbooks.api.intuit.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://oauth.intuit.com/oauth/v1/get_request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://appcenter.intuit.com/Connect/Begin'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://oauth.intuit.com/oauth/v1/get_access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) - || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - $message = 'Error in retrieving token: "' . $data['error'] . '"'; - throw new TokenResponseException($message); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritDoc} - */ - public function request( - $path, - $method = 'GET', - $body = null, - array $extraHeaders = array() - ) { - $extraHeaders['Accept'] = 'application/json'; - return parent::request($path, $method, $body, $extraHeaders); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Redmine.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Redmine.php deleted file mode 100644 index 55f89a2..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Redmine.php +++ /dev/null @@ -1,96 +0,0 @@ -baseApiUri->getAbsoluteUri() . '/request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri($this->baseApiUri->getAbsoluteUri() . '/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri($this->baseApiUri->getAbsoluteUri() . '/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ScoopIt.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ScoopIt.php deleted file mode 100644 index 28bd250..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ScoopIt.php +++ /dev/null @@ -1,96 +0,0 @@ -baseApiUri = new Uri('https://www.scoop.it/api/1/'); - } - } - - /** - * {@inheritDoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://www.scoop.it/oauth/request'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.scoop.it/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.scoop.it/oauth/access'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ServiceInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ServiceInterface.php deleted file mode 100644 index 3f91fbf..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/ServiceInterface.php +++ /dev/null @@ -1,45 +0,0 @@ -baseApiUri = new Uri('https://api.tumblr.com/v2/'); - } - } - - /** - * {@inheritdoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://www.tumblr.com/oauth/request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.tumblr.com/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.tumblr.com/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Twitter.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Twitter.php deleted file mode 100644 index dea680f..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Twitter.php +++ /dev/null @@ -1,123 +0,0 @@ -baseApiUri = new Uri('https://api.twitter.com/1.1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://api.twitter.com/oauth/request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - if ($this->authorizationEndpoint != self::ENDPOINT_AUTHENTICATE - && $this->authorizationEndpoint != self::ENDPOINT_AUTHORIZE) { - $this->authorizationEndpoint = self::ENDPOINT_AUTHENTICATE; - } - return new Uri($this->authorizationEndpoint); - } - - /** - * @param string $authorizationEndpoint - * - * @throws Exception - */ - public function setAuthorizationEndpoint($endpoint) - { - if ($endpoint != self::ENDPOINT_AUTHENTICATE && $endpoint != self::ENDPOINT_AUTHORIZE) { - throw new Exception( - sprintf("'%s' is not a correct Twitter authorization endpoint.", $endpoint) - ); - } - $this->authorizationEndpoint = $endpoint; - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.twitter.com/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response: ' . $responseBody); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } elseif (!isset($data["oauth_token"]) || !isset($data["oauth_token_secret"])) { - throw new TokenResponseException('Invalid response. OAuth Token data not set: ' . $responseBody); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Xing.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Xing.php deleted file mode 100644 index e6824db..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Xing.php +++ /dev/null @@ -1,97 +0,0 @@ -baseApiUri = new Uri('https://api.xing.com/v1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.xing.com/v1/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.xing.com/v1/access_token'); - } - - /** - * {@inheritdoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://api.xing.com/v1/request_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - $errors = json_decode($responseBody); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif ($errors) { - throw new TokenResponseException('Error in retrieving token: "' . $errors->error_name . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Yahoo.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Yahoo.php deleted file mode 100644 index 50a825b..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Service/Yahoo.php +++ /dev/null @@ -1,131 +0,0 @@ -baseApiUri = new Uri('https://social.yahooapis.com/v1/'); - } - } - - /** - * {@inheritDoc} - */ - public function getRequestTokenEndpoint() - { - return new Uri('https://api.login.yahoo.com/oauth/v2/get_request_token'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.login.yahoo.com/oauth/v2/request_auth'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.login.yahoo.com/oauth/v2/get_token'); - } - - /** - * {@inheritdoc} - */ - public function refreshAccessToken(TokenInterface $token) - { - $extraParams = $token->getExtraParams(); - $bodyParams = array('oauth_session_handle' => $extraParams['oauth_session_handle']); - - $authorizationHeader = array( - 'Authorization' => $this->buildAuthorizationHeaderForAPIRequest( - 'POST', - $this->getAccessTokenEndpoint(), - $this->storage->retrieveAccessToken($this->service()), - $bodyParams - ) - ); - - - - $headers = array_merge($authorizationHeader, $this->getExtraOAuthHeaders(), array()); - - $responseBody = $this->httpClient->retrieveResponse($this->getAccessTokenEndpoint(), $bodyParams, $headers); - - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['oauth_callback_confirmed']) || $data['oauth_callback_confirmed'] !== 'true') { - throw new TokenResponseException('Error in retrieving token.'); - } - - return $this->parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth1Token(); - - $token->setRequestToken($data['oauth_token']); - $token->setRequestTokenSecret($data['oauth_token_secret']); - $token->setAccessToken($data['oauth_token']); - $token->setAccessTokenSecret($data['oauth_token_secret']); - - if (isset($data['oauth_expires_in'])) { - $token->setLifetime($data['oauth_expires_in']); - } else { - $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES); - } - - unset($data['oauth_token'], $data['oauth_token_secret']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php deleted file mode 100644 index 44c36ce..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/Exception/UnsupportedHashAlgorithmException.php +++ /dev/null @@ -1,12 +0,0 @@ -credentials = $credentials; - } - - /** - * @param string $algorithm - */ - public function setHashingAlgorithm($algorithm) - { - $this->algorithm = $algorithm; - } - - /** - * @param string $token - */ - public function setTokenSecret($token) - { - $this->tokenSecret = $token; - } - - /** - * @param UriInterface $uri - * @param array $params - * @param string $method - * - * @return string - */ - public function getSignature(UriInterface $uri, array $params, $method = 'POST') - { - parse_str($uri->getQuery(), $queryStringData); - - foreach (array_merge($queryStringData, $params) as $key => $value) { - $signatureData[rawurlencode($key)] = rawurlencode($value); - } - - ksort($signatureData); - - // determine base uri - $baseUri = $uri->getScheme() . '://' . $uri->getRawAuthority(); - - if ('/' === $uri->getPath()) { - $baseUri .= $uri->hasExplicitTrailingHostSlash() ? '/' : ''; - } else { - $baseUri .= $uri->getPath(); - } - - $baseString = strtoupper($method) . '&'; - $baseString .= rawurlencode($baseUri) . '&'; - $baseString .= rawurlencode($this->buildSignatureDataString($signatureData)); - - return base64_encode($this->hash($baseString)); - } - - /** - * @param array $signatureData - * - * @return string - */ - protected function buildSignatureDataString(array $signatureData) - { - $signatureString = ''; - $delimiter = ''; - foreach ($signatureData as $key => $value) { - $signatureString .= $delimiter . $key . '=' . $value; - - $delimiter = '&'; - } - - return $signatureString; - } - - /** - * @return string - */ - protected function getSigningKey() - { - $signingKey = rawurlencode($this->credentials->getConsumerSecret()) . '&'; - if ($this->tokenSecret !== null) { - $signingKey .= rawurlencode($this->tokenSecret); - } - - return $signingKey; - } - - /** - * @param string $data - * - * @return string - * - * @throws UnsupportedHashAlgorithmException - */ - protected function hash($data) - { - switch (strtoupper($this->algorithm)) { - case 'HMAC-SHA1': - return hash_hmac('sha1', $data, $this->getSigningKey(), true); - default: - throw new UnsupportedHashAlgorithmException( - 'Unsupported hashing algorithm (' . $this->algorithm . ') used.' - ); - } - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/SignatureInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/SignatureInterface.php deleted file mode 100644 index da50ddb..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Signature/SignatureInterface.php +++ /dev/null @@ -1,28 +0,0 @@ -requestToken = $requestToken; - } - - /** - * @return string - */ - public function getRequestToken() - { - return $this->requestToken; - } - - /** - * @param string $requestTokenSecret - */ - public function setRequestTokenSecret($requestTokenSecret) - { - $this->requestTokenSecret = $requestTokenSecret; - } - - /** - * @return string - */ - public function getRequestTokenSecret() - { - return $this->requestTokenSecret; - } - - /** - * @param string $accessTokenSecret - */ - public function setAccessTokenSecret($accessTokenSecret) - { - $this->accessTokenSecret = $accessTokenSecret; - } - - /** - * @return string - */ - public function getAccessTokenSecret() - { - return $this->accessTokenSecret; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/TokenInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/TokenInterface.php deleted file mode 100644 index 0bc3f73..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth1/Token/TokenInterface.php +++ /dev/null @@ -1,41 +0,0 @@ -stateParameterInAuthUrl = $stateParameterInAutUrl; - - foreach ($scopes as $scope) { - if (!$this->isValidScope($scope)) { - throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this)); - } - } - - $this->scopes = $scopes; - - $this->baseApiUri = $baseApiUri; - - $this->apiVersion = $apiVersion; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'type' => 'web_server', - 'client_id' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - ) - ); - - $parameters['scope'] = implode($this->getScopesDelimiter(), $this->scopes); - - if ($this->needsStateParameterInAuthUrl()) { - if (!isset($parameters['state'])) { - $parameters['state'] = $this->generateAuthorizationState(); - } - $this->storeAuthorizationState($parameters['state']); - } - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritdoc} - */ - public function requestAccessToken($code, $state = null) - { - if (null !== $state) { - $this->validateAuthorizationState($state); - } - - $bodyParams = array( - 'code' => $code, - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'grant_type' => 'authorization_code', - ); - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenEndpoint(), - $bodyParams, - $this->getExtraOAuthHeaders() - ); - - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - /** - * Sends an authenticated API request to the path provided. - * If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used. - * - * @param string|UriInterface $path - * @param string $method HTTP method - * @param array $body Request body if applicable. - * @param array $extraHeaders Extra headers if applicable. These will override service-specific - * any defaults. - * - * @return string - * - * @throws ExpiredTokenException - * @throws Exception - */ - public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $uri = $this->determineRequestUriFromPath($path, $this->baseApiUri); - $token = $this->storage->retrieveAccessToken($this->service()); - - if ($token->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES - && $token->getEndOfLife() !== TokenInterface::EOL_UNKNOWN - && time() > $token->getEndOfLife() - ) { - throw new ExpiredTokenException( - sprintf( - 'Token expired on %s at %s', - date('m/d/Y', $token->getEndOfLife()), - date('h:i:s A', $token->getEndOfLife()) - ) - ); - } - - // add the token where it may be needed - if (static::AUTHORIZATION_METHOD_HEADER_OAUTH === $this->getAuthorizationMethod()) { - $extraHeaders = array_merge(array('Authorization' => 'OAuth ' . $token->getAccessToken()), $extraHeaders); - } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING === $this->getAuthorizationMethod()) { - $uri->addToQuery('access_token', $token->getAccessToken()); - } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V2 === $this->getAuthorizationMethod()) { - $uri->addToQuery('oauth2_access_token', $token->getAccessToken()); - } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V3 === $this->getAuthorizationMethod()) { - $uri->addToQuery('apikey', $token->getAccessToken()); - } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V4 === $this->getAuthorizationMethod()) { - $uri->addToQuery('auth', $token->getAccessToken()); - } elseif (static::AUTHORIZATION_METHOD_HEADER_BEARER === $this->getAuthorizationMethod()) { - $extraHeaders = array_merge(array('Authorization' => 'Bearer ' . $token->getAccessToken()), $extraHeaders); - } - - $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); - - return $this->httpClient->retrieveResponse($uri, $body, $extraHeaders, $method); - } - - /** - * Accessor to the storage adapter to be able to retrieve tokens - * - * @return TokenStorageInterface - */ - public function getStorage() - { - return $this->storage; - } - - /** - * Refreshes an OAuth2 access token. - * - * @param TokenInterface $token - * - * @return TokenInterface $token - * - * @throws MissingRefreshTokenException - */ - public function refreshAccessToken(TokenInterface $token) - { - $refreshToken = $token->getRefreshToken(); - - if (empty($refreshToken)) { - throw new MissingRefreshTokenException(); - } - - $parameters = array( - 'grant_type' => 'refresh_token', - 'type' => 'web_server', - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'refresh_token' => $refreshToken, - ); - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenEndpoint(), - $parameters, - $this->getExtraOAuthHeaders() - ); - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - /** - * Return whether or not the passed scope value is valid. - * - * @param string $scope - * - * @return bool - */ - public function isValidScope($scope) - { - $reflectionClass = new \ReflectionClass(get_class($this)); - - return in_array($scope, $reflectionClass->getConstants(), true); - } - - /** - * Check if the given service need to generate a unique state token to build the authorization url - * - * @return bool - */ - public function needsStateParameterInAuthUrl() - { - return $this->stateParameterInAuthUrl; - } - - /** - * Validates the authorization state against a given one - * - * @param string $state - * @throws InvalidAuthorizationStateException - */ - protected function validateAuthorizationState($state) - { - if ($this->retrieveAuthorizationState() !== $state) { - throw new InvalidAuthorizationStateException(); - } - } - - /** - * Generates a random string to be used as state - * - * @return string - */ - protected function generateAuthorizationState() - { - return md5(rand()); - } - - /** - * Retrieves the authorization state for the current service - * - * @return string - */ - protected function retrieveAuthorizationState() - { - return $this->storage->retrieveAuthorizationState($this->service()); - } - - /** - * Stores a given authorization state into the storage - * - * @param string $state - */ - protected function storeAuthorizationState($state) - { - $this->storage->storeAuthorizationState($this->service(), $state); - } - - /** - * Return any additional headers always needed for this service implementation's OAuth calls. - * - * @return array - */ - protected function getExtraOAuthHeaders() - { - return array(); - } - - /** - * Return any additional headers always needed for this service implementation's API calls. - * - * @return array - */ - protected function getExtraApiHeaders() - { - return array(); - } - - /** - * Parses the access token response and returns a TokenInterface. - * - * @abstract - * - * @param string $responseBody - * - * @return TokenInterface - * - * @throws TokenResponseException - */ - abstract protected function parseAccessTokenResponse($responseBody); - - /** - * Returns a class constant from ServiceInterface defining the authorization method used for the API - * Header is the sane default. - * - * @return int - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_OAUTH; - } - - /** - * Returns api version string if is set else retrun empty string - * - * @return string - */ - protected function getApiVersionString() - { - return !(empty($this->apiVersion)) ? "/".$this->apiVersion : "" ; - } - - /** - * Returns delimiter to scopes in getAuthorizationUri - * For services that do not fully respect the Oauth's RFC, - * and use scopes with commas as delimiter - * - * @return string - */ - protected function getScopesDelimiter() - { - return ' '; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Amazon.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Amazon.php deleted file mode 100644 index 035d1a5..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Amazon.php +++ /dev/null @@ -1,97 +0,0 @@ - - * @link https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf - */ -class Amazon extends AbstractService -{ - /** - * Defined scopes - * @link https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf - */ - const SCOPE_PROFILE = 'profile'; - const SCOPE_POSTAL_CODE = 'postal_code'; - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.amazon.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.amazon.com/ap/oa'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.amazon.com/ap/oatoken'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error_description'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error_description'] . '"'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitly.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitly.php deleted file mode 100644 index e01cbc4..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitly.php +++ /dev/null @@ -1,111 +0,0 @@ -baseApiUri = new Uri('https://api-ssl.bitly.com/v3/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://bitly.com/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api-ssl.bitly.com/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - // I'm invincible!!! - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - public function requestAccessToken($code, $state = null) - { - if (null !== $state) { - $this->validateAuthorizationState($state); - } - - $bodyParams = array( - 'code' => $code, - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'grant_type' => 'authorization_code', - ); - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenEndpoint(), - $bodyParams, - $this->getExtraOAuthHeaders() - ); - - // we can scream what we want that we want bitly to return a json encoded string (format=json), but the - // WOAH WATCH YOUR LANGUAGE ;) service doesn't seem to like screaming, hence we need to manually - // parse the result - $parsedResult = array(); - parse_str($responseBody, $parsedResult); - - $token = $this->parseAccessTokenResponse(json_encode($parsedResult)); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitrix24.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitrix24.php deleted file mode 100644 index 1630d30..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Bitrix24.php +++ /dev/null @@ -1,118 +0,0 @@ -baseApiUri)); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri(sprintf('%s/oauth/token/', $this->baseApiUri)); - } - - /** - * {@inheritdoc} - */ - public function requestAccessToken($code, $state = null) - { - if (null !== $state) { - $this->validateAuthorizationState($state); - } - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenUri($code), - array(), - $this->getExtraOAuthHeaders(), - 'GET' - ); - - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenUri($code) - { - $parameters = array( - 'code' => $code, - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'grant_type' => 'authorization_code', - 'scope' => $this->scopes - ); - - $parameters['scope'] = implode(' ', $this->scopes); - - // Build the url - $url = $this->getAccessTokenEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Box.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Box.php deleted file mode 100644 index 14696c5..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Box.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @link https://developers.box.com/oauth/ - */ -class Box extends AbstractService -{ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.box.com/2.0/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.box.com/api/oauth2/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.box.com/api/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Buffer.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Buffer.php deleted file mode 100644 index 5905678..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Buffer.php +++ /dev/null @@ -1,151 +0,0 @@ - - * @link https://bufferapp.com/developers/api - */ -class Buffer extends AbstractService -{ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - if ($baseApiUri === null) { - $this->baseApiUri = new Uri('https://api.bufferapp.com/1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://bufferapp.com/oauth2/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.bufferapp.com/1/oauth2/token.json'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'client_id' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - ) - ); - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritdoc} - */ - public function requestRequestToken() - { - $responseBody = $this->httpClient->retrieveResponse( - $this->getRequestTokenEndpoint(), - array( - 'client_key' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - ) - ); - - $code = $this->parseRequestTokenResponse($responseBody); - - return $code; - } - - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['code'])) { - throw new TokenResponseException('Error in retrieving code.'); - } - return $data['code']; - } - - public function requestAccessToken($code) - { - $bodyParams = array( - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'code' => $code, - 'grant_type' => 'authorization_code', - ); - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenEndpoint(), - $bodyParams, - $this->getExtraOAuthHeaders() - ); - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if ($data === null || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - unset($data['access_token']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dailymotion.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dailymotion.php deleted file mode 100644 index 095a467..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dailymotion.php +++ /dev/null @@ -1,129 +0,0 @@ - - * @link http://www.dailymotion.com/doc/api/authentication.html - */ -class Dailymotion extends AbstractService -{ - /** - * Scopes - * - * @var string - */ - const SCOPE_EMAIL = 'email', - SCOPE_PROFILE = 'userinfo', - SCOPE_VIDEOS = 'manage_videos', - SCOPE_COMMENTS = 'manage_comments', - SCOPE_PLAYLIST = 'manage_playlists', - SCOPE_TILES = 'manage_tiles', - SCOPE_SUBSCRIPTIONS = 'manage_subscriptions', - SCOPE_FRIENDS = 'manage_friends', - SCOPE_FAVORITES = 'manage_favorites', - SCOPE_GROUPS = 'manage_groups'; - - /** - * Dialog form factors - * - * @var string - */ - const DISPLAY_PAGE = 'page', - DISPLAY_POPUP = 'popup', - DISPLAY_MOBILE = 'mobile'; - - /** - * {@inheritdoc} - */ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.dailymotion.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.dailymotion.com/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.dailymotion.com/oauth/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_OAUTH; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error_description']) || isset($data['error'])) { - throw new TokenResponseException( - sprintf( - 'Error in retrieving token: "%s"', - isset($data['error_description']) ? $data['error_description'] : $data['error'] - ) - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - return array('Accept' => 'application/json'); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Deezer.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Deezer.php deleted file mode 100644 index 3e3965b..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Deezer.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://developers.deezer.com/api/ - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; - -/** - * Deezer service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://developers.deezer.com/api/ - */ -class Deezer extends AbstractService -{ - /** - * Defined scopes - * http://developers.deezer.com/api/permissions - */ - const SCOPE_BASIC_ACCESS = 'basic_access'; // Access users basic information - const SCOPE_EMAIL = 'email'; // Get the user's email - const SCOPE_OFFLINE_ACCESS = 'offline_access'; // Access user data any time - const SCOPE_MANAGE_LIBRARY = 'manage_library'; // Manage users' library - const SCOPE_MANAGE_COMMUNITY = 'manage_community'; // Manage users' friends - const SCOPE_DELETE_LIBRARY = 'delete_library'; // Delete library items - const SCOPE_LISTENING_HISTORY = 'listening_history'; // Access the user's listening history - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.deezer.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://connect.deezer.com/oauth/auth.php'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://connect.deezer.com/oauth/access_token.php'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - if (null === $data || !is_array($data) || empty($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } elseif (isset($data['error_reason'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error_reason'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires']); - - // I hope one day Deezer add a refresh token :) - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Delicious.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Delicious.php deleted file mode 100644 index eba6035..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Delicious.php +++ /dev/null @@ -1,139 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://github.com/SciDevs/delicious-api/blob/master/api/oauth.md - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; - -/** - * Delicious service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://github.com/SciDevs/delicious-api/blob/master/api/oauth.md - */ -class Delicious extends AbstractService -{ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.del.icio.us/v1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://delicious.com/auth/authorize'); - - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://avosapi.delicious.com/api/v1/oauth/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires_in'])) { - $token->setLifetime($data['expires_in']); - unset($data['expires_in']); - } - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - - // Special, delicious didn't respect the oauth2 RFC and need a grant_type='code' - /** - * {@inheritdoc} - */ - public function requestAccessToken($code, $state = null) - { - if (null !== $state) { - $this->validateAuthorizationState($state); - } - - $bodyParams = array( - 'code' => $code, - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'grant_type' => 'code', - ); - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenEndpoint(), - $bodyParams, - $this->getExtraOAuthHeaders() - ); - - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/DeviantArt.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/DeviantArt.php deleted file mode 100644 index 31e94b4..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/DeviantArt.php +++ /dev/null @@ -1,99 +0,0 @@ -baseApiUri = new Uri('https://www.deviantart.com/api/v1/oauth2/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.deviantart.com/oauth2/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.deviantart.com/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires_in'])) { - $token->setLifeTime($data['expires_in']); - } - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dropbox.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dropbox.php deleted file mode 100644 index 43ec6c7..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Dropbox.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @link https://www.dropbox.com/developers/core/docs - */ -class Dropbox extends AbstractService -{ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.dropbox.com/1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'client_id' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - ) - ); - - $parameters['scope'] = implode(' ', $this->scopes); - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.dropbox.com/1/oauth2/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.dropbox.com/1/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/EveOnline.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/EveOnline.php deleted file mode 100644 index 76fafa6..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/EveOnline.php +++ /dev/null @@ -1,100 +0,0 @@ - - */ -namespace OAuth\OAuth2\Service; - -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Http\Uri\UriInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Token\TokenInterface; -use OAuth\OAuth2\Token\StdOAuth2Token; - -/** - * Class EveOnline - */ -class EveOnline extends AbstractService -{ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://login.eveonline.com'); - } - } - - /** - * Returns the authorization API endpoint. - * @return UriInterface - */ - public function getAuthorizationEndpoint() - { - return new Uri($this->baseApiUri . '/oauth/authorize'); - } - - /** - * Returns the access token API endpoint. - * @return UriInterface - */ - public function getAccessTokenEndpoint() - { - return new Uri($this->baseApiUri . '/oauth/token'); - } - - /** - * Parses the access token response and returns a TokenInterface. - * - * @param string $responseBody - * - * @return TokenInterface - * @throws TokenResponseException - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error_description'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error_description'] . '"'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php deleted file mode 100644 index 398df2f..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/InvalidAccessTypeException.php +++ /dev/null @@ -1,12 +0,0 @@ - - * Released under the MIT license. - */ - -namespace OAuth\OAuth2\Service\Exception; - -use OAuth\Common\Exception\Exception; - -/** - * Exception thrown when a scope provided to a service is invalid. - */ -class InvalidScopeException extends Exception -{ -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php deleted file mode 100644 index 21eece6..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Exception/MissingRefreshTokenException.php +++ /dev/null @@ -1,17 +0,0 @@ - - * Released under the MIT license. - */ - -namespace OAuth\OAuth2\Service\Exception; - -use OAuth\Common\Exception\Exception; - -/** - * Exception thrown when service is requested to refresh the access token but no refresh token can be found. - */ -class MissingRefreshTokenException extends Exception -{ -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Facebook.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Facebook.php deleted file mode 100644 index 308513b..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Facebook.php +++ /dev/null @@ -1,208 +0,0 @@ -baseApiUri = new Uri('https://graph.facebook.com'.$this->getApiVersionString().'/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.facebook.com'.$this->getApiVersionString().'/dialog/oauth'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://graph.facebook.com'.$this->getApiVersionString().'/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - // Facebook gives us a query string ... Oh wait. JSON is too simple, understand ? - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires'])) { - $token->setLifeTime($data['expires']); - } - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires']); - - $token->setExtraParams($data); - - return $token; - } - - public function getDialogUri($dialogPath, array $parameters) - { - if (!isset($parameters['redirect_uri'])) { - throw new Exception("Redirect uri is mandatory for this request"); - } - $parameters['app_id'] = $this->credentials->getConsumerId(); - $baseUrl = self::WWW_URL .$this->getApiVersionString(). '/dialog/' . $dialogPath; - $query = http_build_query($parameters); - return new Uri($baseUrl . '?' . $query); - } - - /** - * {@inheritdoc} - */ - protected function getScopesDelimiter() - { - return ','; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Foursquare.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Foursquare.php deleted file mode 100644 index 981ff44..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Foursquare.php +++ /dev/null @@ -1,81 +0,0 @@ -baseApiUri = new Uri('https://api.foursquare.com/v2/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://foursquare.com/oauth2/authenticate'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://foursquare.com/oauth2/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - // Foursquare tokens evidently never expire... - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - $uri = $this->determineRequestUriFromPath($path, $this->baseApiUri); - $uri->addToQuery('v', $this->apiVersionDate); - - return parent::request($uri, $method, $body, $extraHeaders); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/GitHub.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/GitHub.php deleted file mode 100644 index 8d4d122..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/GitHub.php +++ /dev/null @@ -1,216 +0,0 @@ -baseApiUri = new Uri('https://api.github.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://github.com/login/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://github.com/login/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - // Github tokens evidently never expire... - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * Used to configure response type -- we want JSON from github, default is query string format - * - * @return array - */ - protected function getExtraOAuthHeaders() - { - return array('Accept' => 'application/json'); - } - - /** - * Required for GitHub API calls. - * - * @return array - */ - protected function getExtraApiHeaders() - { - return array('Accept' => 'application/vnd.github.beta+json'); - } - - /** - * {@inheritdoc} - */ - protected function getScopesDelimiter() - { - return ','; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Google.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Google.php deleted file mode 100644 index 8fa556a..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Google.php +++ /dev/null @@ -1,190 +0,0 @@ -baseApiUri = new Uri('https://www.googleapis.com/oauth2/v1/'); - } - } - - public function setAccessType($accessType) - { - if (!in_array($accessType, array('online', 'offline'), true)) { - throw new InvalidAccessTypeException('Invalid accessType, expected either online or offline'); - } - $this->accessType = $accessType; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://accounts.google.com/o/oauth2/auth?access_type=' . $this->accessType); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://accounts.google.com/o/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Harvest.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Harvest.php deleted file mode 100644 index 96fb0f2..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Harvest.php +++ /dev/null @@ -1,157 +0,0 @@ -baseApiUri = new Uri('https://api.harvestapp.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'client_id' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'state' => 'optional-csrf-token', - 'response_type' => 'code', - ) - ); - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.harvestapp.com/oauth2/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.harvestapp.com/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || ! is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - $token->setRefreshToken($data['refresh_token']); - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * Refreshes an OAuth2 access token. - * - * @param TokenInterface $token - * - * @return TokenInterface $token - * - * @throws MissingRefreshTokenException - */ - public function refreshAccessToken(TokenInterface $token) - { - $refreshToken = $token->getRefreshToken(); - - if (empty($refreshToken)) { - throw new MissingRefreshTokenException(); - } - - $parameters = array( - 'grant_type' => 'refresh_token', - 'type' => 'web_server', - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'refresh_token' => $refreshToken, - ); - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenEndpoint(), - $parameters, - $this->getExtraOAuthHeaders() - ); - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - /** - * @return array - */ - protected function getExtraOAuthHeaders() - { - return array('Accept' => 'application/json'); - } - - /** - * Return any additional headers always needed for this service implementation's API calls. - * - * @return array - */ - protected function getExtraApiHeaders() - { - return array('Accept' => 'application/json'); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Heroku.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Heroku.php deleted file mode 100644 index 470cedc..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Heroku.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @link https://devcenter.heroku.com/articles/oauth - */ -class Heroku extends AbstractService -{ - /** - * Defined scopes - * @link https://devcenter.heroku.com/articles/oauth#scopes - */ - const SCOPE_GLOBAL = 'global'; - const SCOPE_IDENTITY = 'identity'; - const SCOPE_READ = 'read'; - const SCOPE_WRITE = 'write'; - const SCOPE_READ_PROTECTED = 'read-protected'; - const SCOPE_WRITE_PROTECTED = 'write-protected'; - - /** - * {@inheritdoc} - */ - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.heroku.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://id.heroku.com/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://id.heroku.com/oauth/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error_description']) || isset($data['error'])) { - throw new TokenResponseException( - sprintf( - 'Error in retrieving token: "%s"', - isset($data['error_description']) ? $data['error_description'] : $data['error'] - ) - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - return array('Accept' => 'application/vnd.heroku+json; version=3'); - } - - /** - * {@inheritdoc} - */ - protected function getExtraApiHeaders() - { - return array('Accept' => 'application/vnd.heroku+json; version=3', 'Content-Type' => 'application/json'); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Hubic.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Hubic.php deleted file mode 100644 index b995450..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Hubic.php +++ /dev/null @@ -1,155 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://api.hubic.com/docs/ - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; - -/** - * Hubic service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://api.hubic.com/docs/ - */ -class Hubic extends AbstractService -{ - - // Scopes - const SCOPE_USAGE_GET = 'usage.r'; - const SCOPE_ACCOUNT_GET = 'account.r'; - const SCOPE_GETALLLINKS_GET = 'getAllLinks.r'; - const SCOPE_CREDENTIALS_GET = 'credentials.r'; - const SCOPE_SPONSORCODE_GET = 'sponsorCode.r'; - const SCOPE_ACTIVATE_POST = 'activate.w'; - const SCOPE_SPONSORED_GET = 'sponsored.r'; - const SCOPE_LINKS_GET = 'links.r'; - const SCOPE_LINKS_POST = 'links.rw'; - const SCOPE_LINKS_ALL = 'links.drw'; - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.hubic.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.hubic.com/oauth/auth'); - - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.hubic.com/oauth/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'type' => 'web_server', - 'client_id' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - ) - ); - - // special, hubic use a param scope with commas - // between scopes instead of spaces - $parameters['scope'] = implode(',', $this->scopes); - - if ($this->needsStateParameterInAuthUrl()) { - if (!isset($parameters['state'])) { - $parameters['state'] = $this->generateAuthorizationState(); - } - $this->storeAuthorizationState($parameters['state']); - } - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Instagram.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Instagram.php deleted file mode 100644 index c60c455..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Instagram.php +++ /dev/null @@ -1,85 +0,0 @@ -baseApiUri = new Uri('https://api.instagram.com/v1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.instagram.com/oauth/authorize/'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.instagram.com/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - // Instagram tokens evidently never expire... - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/JawboneUP.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/JawboneUP.php deleted file mode 100644 index fad1125..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/JawboneUP.php +++ /dev/null @@ -1,144 +0,0 @@ - - * @link https://jawbone.com/up/developer/authentication - */ -class JawboneUP extends AbstractService -{ - /** - * Defined scopes - * - * - * @link https://jawbone.com/up/developer/authentication - */ - // general information scopes - const SCOPE_BASIC_READ = 'basic_read'; - const SCOPE_EXTENDED_READ = 'extended_read'; - const SCOPE_LOCATION_READ = 'location_read'; - const SCOPE_FRIENDS_READ = 'friends_read'; - // mood scopes - const SCOPE_MOOD_READ = 'mood_read'; - const SCOPE_MOOD_WRITE = 'mood_write'; - // move scopes - const SCOPE_MOVE_READ = 'move_read'; - const SCOPE_MOVE_WRITE = 'move_write'; - // sleep scopes - const SCOPE_SLEEP_READ = 'sleep_read'; - const SCOPE_SLEEP_WRITE = 'sleep_write'; - // meal scopes - const SCOPE_MEAL_READ = 'meal_read'; - const SCOPE_MEAL_WRITE = 'meal_write'; - // weight scopes - const SCOPE_WEIGHT_READ = 'weight_read'; - const SCOPE_WEIGHT_WRITE = 'weight_write'; - // generic event scopes - const SCOPE_GENERIC_EVENT_READ = 'generic_event_read'; - const SCOPE_GENERIC_EVENT_WRITE = 'generic_event_write'; - - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://jawbone.com/nudge/api/v.1.1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'client_id' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - ) - ); - - $parameters['scope'] = implode(' ', $this->scopes); - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://jawbone.com/auth/oauth2/auth'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://jawbone.com/auth/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Linkedin.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Linkedin.php deleted file mode 100644 index 65cfd94..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Linkedin.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @link http://developer.linkedin.com/documents/authentication - */ -class Linkedin extends AbstractService -{ - /** - * Defined scopes - * @link http://developer.linkedin.com/documents/authentication#granting - */ - const SCOPE_R_BASICPROFILE = 'r_basicprofile'; - const SCOPE_R_FULLPROFILE = 'r_fullprofile'; - const SCOPE_R_EMAILADDRESS = 'r_emailaddress'; - const SCOPE_R_NETWORK = 'r_network'; - const SCOPE_R_CONTACTINFO = 'r_contactinfo'; - const SCOPE_RW_NUS = 'rw_nus'; - const SCOPE_RW_COMPANY_ADMIN = 'rw_company_admin'; - const SCOPE_RW_GROUPS = 'rw_groups'; - const SCOPE_W_MESSAGES = 'w_messages'; - const SCOPE_W_SHARE = 'w_share'; - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri, true); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.linkedin.com/v1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.linkedin.com/uas/oauth2/authorization'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.linkedin.com/uas/oauth2/accessToken'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Mailchimp.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Mailchimp.php deleted file mode 100644 index 842153d..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Mailchimp.php +++ /dev/null @@ -1,114 +0,0 @@ -baseApiUri) && $storage->hasAccessToken($this->service())) { - $this->setBaseApiUri($storage->retrieveAccessToken($this->service())); - } - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING_V3; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://login.mailchimp.com/oauth2/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://login.mailchimp.com/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - // Parse JSON - $data = json_decode($responseBody, true); - - // Do validation. - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - // Create token object. - $token = new StdOAuth2Token($data['access_token']); - - // Set the right API endpoint. - $this->setBaseApiUri($token); - - // Mailchimp tokens evidently never expire... - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - - return $token; - } - - /** - * {@inheritdoc} - */ - public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) - { - if (is_null($this->baseApiUri)) { - $this->setBaseApiUri($this->storage->retrieveAccessToken($this->service())); - } - - return parent::request($path, $method, $body, $extraHeaders); - } - - /** - * Set the right base endpoint. - * - * @param StdOAuth2Token $token - */ - protected function setBaseApiUri(StdOAuth2Token $token) - { - // Make request uri. - $endpoint = 'https://login.mailchimp.com/oauth2/metadata?oauth_token='. $token->getAccessToken(); - - // Grab meta data about the token. - $response = $this->httpClient->retrieveResponse(new Uri($endpoint), array(), array(), 'GET'); - - // Parse JSON. - $meta = json_decode($response, true); - - // Set base api uri. - $this->baseApiUri = new Uri('https://'. $meta['dc'] .'.api.mailchimp.com/2.0/'); - - // Allow chaining. - return $this; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Microsoft.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Microsoft.php deleted file mode 100644 index c815b22..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Microsoft.php +++ /dev/null @@ -1,120 +0,0 @@ -baseApiUri = new Uri('https://apis.live.net/v5.0/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://login.live.com/oauth20_authorize.srf'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://login.live.com/oauth20_token.srf'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Nest.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Nest.php deleted file mode 100644 index 7659e4f..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Nest.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developer.nest.com/documentation - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; - -/** - * Nest service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developer.nest.com/documentation - */ -class Nest extends AbstractService -{ - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://developer-api.nest.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://home.nest.com/login/oauth2'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.home.nest.com/oauth2/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING_V4; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Netatmo.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Netatmo.php deleted file mode 100644 index eb5c68d..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Netatmo.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://dev.netatmo.com/doc/ - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; - -/** - * Netatmo service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://dev.netatmo.com/doc/ - */ -class Netatmo extends AbstractService -{ - - // SCOPES - // @link https://dev.netatmo.com/doc/authentication/scopes - - // Used to read weather station's data (devicelist, getmeasure) - const SCOPE_STATION_READ = 'read_station'; - // Used to read thermostat's data (devicelist, getmeasure, getthermstate) - const SCOPE_THERMOSTAT_READ = 'read_thermostat'; - // Used to configure the thermostat (syncschedule, setthermpoint) - const SCOPE_THERMOSTAT_WRITE = 'write_thermostat'; - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true // use parameter state - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.netatmo.net/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri($this->baseApiUri.'oauth2/authorize'); - - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri($this->baseApiUri.'oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ParrotFlowerPower.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ParrotFlowerPower.php deleted file mode 100644 index 78ef942..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ParrotFlowerPower.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://flowerpowerdev.parrot.com/projects/flower-power-web-service-api/wiki - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; -use OAuth\OAuth2\Service\Exception\MissingRefreshTokenException; -use OAuth\Common\Token\TokenInterface; - -/** - * ParrotFlowerPower service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://flowerpowerdev.parrot.com/projects/flower-power-web-service-api/wiki - */ -class ParrotFlowerPower extends AbstractService -{ - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://apiflowerpower.parrot.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri($this->baseApiUri.'oauth2/v1/authorize'); - - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri($this->baseApiUri.'user/v1/authenticate'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - - /** - * Parrot use a different endpoint for refresh a token - * - * {@inheritdoc} - */ - public function refreshAccessToken(TokenInterface $token) - { - $refreshToken = $token->getRefreshToken(); - - if (empty($refreshToken)) { - throw new MissingRefreshTokenException(); - } - - $parameters = array( - 'grant_type' => 'refresh_token', - 'type' => 'web_server', - 'client_id' => $this->credentials->getConsumerId(), - 'client_secret' => $this->credentials->getConsumerSecret(), - 'refresh_token' => $refreshToken, - ); - - $responseBody = $this->httpClient->retrieveResponse( - new Uri($this->baseApiUri.'user/v1/refresh'), - $parameters, - $this->getExtraOAuthHeaders() - ); - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Paypal.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Paypal.php deleted file mode 100644 index 761c09d..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Paypal.php +++ /dev/null @@ -1,103 +0,0 @@ - - * @link https://developer.paypal.com/webapps/developer/docs/integration/direct/log-in-with-paypal/detailed/ - */ -class Paypal extends AbstractService -{ - /** - * Defined scopes - * @link https://developer.paypal.com/webapps/developer/docs/integration/direct/log-in-with-paypal/detailed/ - * @see #attributes - */ - const SCOPE_OPENID = 'openid'; - const SCOPE_PROFILE = 'profile'; - const SCOPE_PAYPALATTRIBUTES = 'https://uri.paypal.com/services/paypalattributes'; - const SCOPE_EMAIL = 'email'; - const SCOPE_ADDRESS = 'address'; - const SCOPE_PHONE = 'phone'; - const SCOPE_EXPRESSCHECKOUT = 'https://uri.paypal.com/services/expresscheckout'; - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.paypal.com/v1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.paypal.com/v1/identity/openidconnect/tokenservice'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['message'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['message'] . '"'); - } elseif (isset($data['name'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['name'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pinterest.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pinterest.php deleted file mode 100644 index e7ecd3c..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pinterest.php +++ /dev/null @@ -1,117 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developers.pinterest.com/docs/api/overview/ - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; - -/** - * Pinterest service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developers.pinterest.com/docs/api/overview/ - */ -class Pinterest extends AbstractService -{ - /** - * Defined scopes - More scopes are listed here: - * https://developers.pinterest.com/docs/api/overview/ - */ - const SCOPE_READ_PUBLIC = 'read_public'; // read a user’s Pins, boards and likes - const SCOPE_WRITE_PUBLIC = 'write_public'; // write Pins, boards, likes - const SCOPE_READ_RELATIONSHIPS = 'read_relationships'; // read a user’s follows (boards, users, interests) - const SCOPE_WRITE_RELATIONSHIPS = 'write_relationships'; // follow boards, users and interests - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.pinterest.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.pinterest.com/oauth/'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.pinterest.com/v1/oauth/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires_in'])) { - $token->setLifeTime($data['expires_in']); - unset($data['expires_in']); - } - // I hope one day Pinterest add a refresh token :) - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pocket.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pocket.php deleted file mode 100644 index 8c95544..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Pocket.php +++ /dev/null @@ -1,125 +0,0 @@ -baseApiUri = new Uri('https://getpocket.com/v3/'); - } - } - - public function getRequestTokenEndpoint() - { - return new Uri('https://getpocket.com/v3/oauth/request'); - } - - public function getAuthorizationEndpoint() - { - return new Uri('https://getpocket.com/auth/authorize'); - } - - public function getAccessTokenEndpoint() - { - return new Uri('https://getpocket.com/v3/oauth/authorize'); - } - - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'redirect_uri' => $this->credentials->getCallbackUrl(), - ) - ); - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - public function requestRequestToken() - { - $responseBody = $this->httpClient->retrieveResponse( - $this->getRequestTokenEndpoint(), - array( - 'consumer_key' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - ) - ); - - $code = $this->parseRequestTokenResponse($responseBody); - - return $code; - } - - protected function parseRequestTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (!isset($data['code'])) { - throw new TokenResponseException('Error in retrieving code.'); - } - return $data['code']; - } - - public function requestAccessToken($code) - { - $bodyParams = array( - 'consumer_key' => $this->credentials->getConsumerId(), - 'code' => $code, - ); - - $responseBody = $this->httpClient->retrieveResponse( - $this->getAccessTokenEndpoint(), - $bodyParams, - $this->getExtraOAuthHeaders() - ); - $token = $this->parseAccessTokenResponse($responseBody); - $this->storage->storeAccessToken($this->service(), $token); - - return $token; - } - - protected function parseAccessTokenResponse($responseBody) - { - parse_str($responseBody, $data); - - if ($data === null || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - #$token->setRequestToken($data['access_token']); - $token->setAccessToken($data['access_token']); - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - unset($data['access_token']); - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Reddit.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Reddit.php deleted file mode 100644 index 9e524d1..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Reddit.php +++ /dev/null @@ -1,114 +0,0 @@ -baseApiUri = new Uri('https://oauth.reddit.com'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://ssl.reddit.com/api/v1/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://ssl.reddit.com/api/v1/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - // Reddit uses a Basic OAuth header - return array('Authorization' => 'Basic ' . - base64_encode($this->credentials->getConsumerId() . ':' . $this->credentials->getConsumerSecret())); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/RunKeeper.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/RunKeeper.php deleted file mode 100644 index 7158407..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/RunKeeper.php +++ /dev/null @@ -1,105 +0,0 @@ -baseApiUri = new Uri('https://api.runkeeper.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationUri(array $additionalParameters = array()) - { - $parameters = array_merge( - $additionalParameters, - array( - 'client_id' => $this->credentials->getConsumerId(), - 'redirect_uri' => $this->credentials->getCallbackUrl(), - 'response_type' => 'code', - ) - ); - - $parameters['scope'] = implode(' ', $this->scopes); - - // Build the url - $url = clone $this->getAuthorizationEndpoint(); - foreach ($parameters as $key => $val) { - $url->addToQuery($key, $val); - } - - return $url; - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://runkeeper.com/apps/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://runkeeper.com/apps/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Salesforce.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Salesforce.php deleted file mode 100644 index a50de11..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Salesforce.php +++ /dev/null @@ -1,92 +0,0 @@ -parseAccessTokenResponse($responseBody); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - // Salesforce tokens evidently never expire... - $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES); - unset($data['access_token']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - return array('Accept' => 'application/json'); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ServiceInterface.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ServiceInterface.php deleted file mode 100644 index e689a4c..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/ServiceInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -baseApiUri = new Uri('https://api.soundcloud.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://soundcloud.com/connect'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.soundcloud.com/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires_in'])) { - $token->setLifetime($data['expires_in']); - unset($data['expires_in']); - } - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Spotify.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Spotify.php deleted file mode 100644 index 22f645b..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Spotify.php +++ /dev/null @@ -1,112 +0,0 @@ -baseApiUri = new Uri('https://api.spotify.com/v1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://accounts.spotify.com/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://accounts.spotify.com/api/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires_in'])) { - $token->setLifetime($data['expires_in']); - unset($data['expires_in']); - } - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - return array('Authorization' => 'Basic ' . - base64_encode($this->credentials->getConsumerId() . ':' . $this->credentials->getConsumerSecret())); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Strava.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Strava.php deleted file mode 100644 index 208ec63..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Strava.php +++ /dev/null @@ -1,147 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://strava.github.io/ - * @link http://strava.github.io/api/v3/oauth/ - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; -use OAuth\OAuth2\Service\Exception\InvalidAccessTypeException; - -/** - * Strava service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://strava.github.io/ - * @link http://strava.github.io/api/v3/oauth/ - */ -class Strava extends AbstractService -{ - /** - * Scopes - */ - // default - const SCOPE_PUBLIC = 'public'; - // Modify activities, upload on the user’s behalf - const SCOPE_WRITE = 'write'; - // View private activities and data within privacy zones - const SCOPE_VIEW_PRIVATE = 'view_private'; - - protected $approvalPrompt = 'auto'; - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - if (empty($scopes)) { - $scopes = array(self::SCOPE_PUBLIC); - } - - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://www.strava.com/api/v3/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.strava.com/oauth/authorize?approval_prompt=' . $this->approvalPrompt); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.strava.com/oauth/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error_description'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error_description'] . '"' - ); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires_in'])) { - $token->setLifeTime($data['expires_in']); - unset($data['expires_in']); - } - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - public function setApprouvalPrompt($prompt) - { - if (!in_array($prompt, array('auto', 'force'), true)) { - // @todo Maybe could we rename this exception - throw new InvalidAccessTypeException('Invalid approuvalPrompt, expected either auto or force.'); - } - $this->approvalPrompt = $prompt; - } - - /** - * {@inheritdoc} - */ - protected function getScopesDelimiter() - { - return ','; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Ustream.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Ustream.php deleted file mode 100644 index 7e55815..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Ustream.php +++ /dev/null @@ -1,98 +0,0 @@ -baseApiUri = new Uri('https://api.ustream.tv/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.ustream.tv/oauth2/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.ustream.tv/oauth2/token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - return array('Authorization' => 'Basic ' . $this->credentials->getConsumerSecret()); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vimeo.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vimeo.php deleted file mode 100644 index 2efe6b2..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vimeo.php +++ /dev/null @@ -1,156 +0,0 @@ - - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developer.vimeo.com/ - * @link https://developer.vimeo.com/api/authentication - */ - -namespace OAuth\OAuth2\Service; - -use OAuth\OAuth2\Token\StdOAuth2Token; -use OAuth\Common\Http\Exception\TokenResponseException; -use OAuth\Common\Http\Uri\Uri; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Uri\UriInterface; - -/** - * Vimeo service. - * - * @author Pedro Amorim - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link https://developer.vimeo.com/ - * @link https://developer.vimeo.com/api/authentication - */ -class Vimeo extends AbstractService -{ - // API version - const VERSION = '3.2'; - // API Header Accept - const HEADER_ACCEPT = 'application/vnd.vimeo.*+json;version=3.2'; - - /** - * Scopes - * @see https://developer.vimeo.com/api/authentication#scope - */ - // View public videos - const SCOPE_PUBLIC = 'public'; - // View private videos - const SCOPE_PRIVATE = 'private'; - // View Vimeo On Demand purchase history - const SCOPE_PURCHASED = 'purchased'; - // Create new videos, groups, albums, etc. - const SCOPE_CREATE = 'create'; - // Edit videos, groups, albums, etc. - const SCOPE_EDIT = 'edit'; - // Delete videos, groups, albums, etc. - const SCOPE_DELETE = 'delete'; - // Interact with a video on behalf of a user, such as liking - // a video or adding it to your watch later queue - const SCOPE_INTERACT = 'interact'; - // Upload a video - const SCOPE_UPLOAD = 'upload'; - - public function __construct( - CredentialsInterface $credentials, - ClientInterface $httpClient, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null - ) { - parent::__construct( - $credentials, - $httpClient, - $storage, - $scopes, - $baseApiUri, - true - ); - - if (null === $baseApiUri) { - $this->baseApiUri = new Uri('https://api.vimeo.com/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://api.vimeo.com/oauth/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://api.vimeo.com/oauth/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error_description'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error_description'] . '"' - ); - } elseif (isset($data['error'])) { - throw new TokenResponseException( - 'Error in retrieving token: "' . $data['error'] . '"' - ); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - - if (isset($data['expires_in'])) { - $token->setLifeTime($data['expires_in']); - unset($data['expires_in']); - } - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - return array('Accept' => self::HEADER_ACCEPT); - } - - /** - * {@inheritdoc} - */ - protected function getExtraApiHeaders() - { - return array('Accept' => self::HEADER_ACCEPT); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vkontakte.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vkontakte.php deleted file mode 100644 index 4a7744e..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Vkontakte.php +++ /dev/null @@ -1,109 +0,0 @@ -baseApiUri = new Uri('https://api.vk.com/method/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://oauth.vk.com/authorize'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://oauth.vk.com/access_token'); - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']); - $token->setLifeTime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_QUERY_STRING; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yahoo.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yahoo.php deleted file mode 100644 index ee5e985..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yahoo.php +++ /dev/null @@ -1,76 +0,0 @@ -setAccessToken($data['access_token']); - $token->setLifetime($data['expires_in']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } - - /** - * {@inheritdoc} - */ - protected function getExtraOAuthHeaders() - { - $encodedCredentials = base64_encode( - $this->credentials->getConsumerId() . ':' . $this->credentials->getConsumerSecret() - ); - return array('Authorization' => 'Basic ' . $encodedCredentials); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yammer.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yammer.php deleted file mode 100644 index 994a293..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Service/Yammer.php +++ /dev/null @@ -1,82 +0,0 @@ -baseApiUri = new Uri('https://www.yammer.com/api/v1/'); - } - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationEndpoint() - { - return new Uri('https://www.yammer.com/dialog/oauth'); - } - - /** - * {@inheritdoc} - */ - public function getAccessTokenEndpoint() - { - return new Uri('https://www.yammer.com/oauth2/access_token.json'); - } - - /** - * {@inheritdoc} - */ - public function getAuthorizationMethod() - { - return static::AUTHORIZATION_METHOD_HEADER_BEARER; - } - - /** - * {@inheritdoc} - */ - protected function parseAccessTokenResponse($responseBody) - { - $data = json_decode($responseBody, true); - - if (null === $data || !is_array($data)) { - throw new TokenResponseException('Unable to parse response.'); - } elseif (isset($data['error'])) { - throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"'); - } - - $token = new StdOAuth2Token(); - $token->setAccessToken($data['access_token']['token']); - $token->setLifetime($data['access_token']['expires_at']); - - if (isset($data['refresh_token'])) { - $token->setRefreshToken($data['refresh_token']); - unset($data['refresh_token']); - } - - unset($data['access_token']); - unset($data['expires_in']); - - $token->setExtraParams($data); - - return $token; - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/StdOAuth2Token.php b/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/StdOAuth2Token.php deleted file mode 100644 index eaaacac..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/OAuth2/Token/StdOAuth2Token.php +++ /dev/null @@ -1,13 +0,0 @@ - - * @author Pieter Hordijk - * @copyright Copyright (c) 2013 The authors - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace OAuth; - -use OAuth\Common\Service\ServiceInterface; -use OAuth\Common\Consumer\CredentialsInterface; -use OAuth\Common\Storage\TokenStorageInterface; -use OAuth\Common\Http\Client\ClientInterface; -use OAuth\Common\Http\Client\StreamClient; -use OAuth\Common\Http\Uri\UriInterface; -use OAuth\Common\Exception\Exception; -use OAuth\OAuth1\Signature\Signature; - -class ServiceFactory -{ - /** - *@var ClientInterface - */ - protected $httpClient; - - /** - * @var array - */ - protected $serviceClassMap = array( - 'OAuth1' => array(), - 'OAuth2' => array() - ); - - /** - * @var array - */ - protected $serviceBuilders = array( - 'OAuth2' => 'buildV2Service', - 'OAuth1' => 'buildV1Service', - ); - - /** - * @param ClientInterface $httpClient - * - * @return ServiceFactory - */ - public function setHttpClient(ClientInterface $httpClient) - { - $this->httpClient = $httpClient; - - return $this; - } - - /** - * Register a custom service to classname mapping. - * - * @param string $serviceName Name of the service - * @param string $className Class to instantiate - * - * @return ServiceFactory - * - * @throws Exception If the class is nonexistent or does not implement a valid ServiceInterface - */ - public function registerService($serviceName, $className) - { - if (!class_exists($className)) { - throw new Exception(sprintf('Service class %s does not exist.', $className)); - } - - $reflClass = new \ReflectionClass($className); - - foreach (array('OAuth2', 'OAuth1') as $version) { - if ($reflClass->implementsInterface('OAuth\\' . $version . '\\Service\\ServiceInterface')) { - $this->serviceClassMap[$version][ucfirst($serviceName)] = $className; - - return $this; - } - } - - throw new Exception(sprintf('Service class %s must implement ServiceInterface.', $className)); - } - - /** - * Builds and returns oauth services - * - * It will first try to build an OAuth2 service and if none found it will try to build an OAuth1 service - * - * @param string $serviceName Name of service to create - * @param CredentialsInterface $credentials - * @param TokenStorageInterface $storage - * @param array|null $scopes If creating an oauth2 service, array of scopes - * @param UriInterface|null $baseApiUri - * @param string $apiVersion version of the api call - * - * @return ServiceInterface - */ - public function createService( - $serviceName, - CredentialsInterface $credentials, - TokenStorageInterface $storage, - $scopes = array(), - UriInterface $baseApiUri = null, - $apiVersion = "" - ) { - if (!$this->httpClient) { - // for backwards compatibility. - $this->httpClient = new StreamClient(); - } - - foreach ($this->serviceBuilders as $version => $buildMethod) { - $fullyQualifiedServiceName = $this->getFullyQualifiedServiceName($serviceName, $version); - - if (class_exists($fullyQualifiedServiceName)) { - return $this->$buildMethod( - $fullyQualifiedServiceName, - $credentials, - $storage, - $scopes, - $baseApiUri, - $apiVersion - ); - } - } - - return null; - } - - /** - * Gets the fully qualified name of the service - * - * @param string $serviceName The name of the service of which to get the fully qualified name - * @param string $type The type of the service to get (either OAuth1 or OAuth2) - * - * @return string The fully qualified name of the service - */ - private function getFullyQualifiedServiceName($serviceName, $type) - { - $serviceName = ucfirst($serviceName); - - if (isset($this->serviceClassMap[$type][$serviceName])) { - return $this->serviceClassMap[$type][$serviceName]; - } - - return '\\OAuth\\' . $type . '\\Service\\' . $serviceName; - } - - /** - * Builds v2 services - * - * @param string $serviceName The fully qualified service name - * @param CredentialsInterface $credentials - * @param TokenStorageInterface $storage - * @param array|null $scopes Array of scopes for the service - * @param UriInterface|null $baseApiUri - * - * @return ServiceInterface - * - * @throws Exception - */ - private function buildV2Service( - $serviceName, - CredentialsInterface $credentials, - TokenStorageInterface $storage, - array $scopes, - UriInterface $baseApiUri = null, - $apiVersion = "" - ) { - return new $serviceName( - $credentials, - $this->httpClient, - $storage, - $this->resolveScopes($serviceName, $scopes), - $baseApiUri, - $apiVersion - ); - } - - /** - * Resolves scopes for v2 services - * - * @param string $serviceName The fully qualified service name - * @param array $scopes List of scopes for the service - * - * @return array List of resolved scopes - */ - private function resolveScopes($serviceName, array $scopes) - { - $reflClass = new \ReflectionClass($serviceName); - $constants = $reflClass->getConstants(); - - $resolvedScopes = array(); - foreach ($scopes as $scope) { - $key = strtoupper('SCOPE_' . $scope); - - if (array_key_exists($key, $constants)) { - $resolvedScopes[] = $constants[$key]; - } else { - $resolvedScopes[] = $scope; - } - } - - return $resolvedScopes; - } - - /** - * Builds v1 services - * - * @param string $serviceName The fully qualified service name - * @param CredentialsInterface $credentials - * @param TokenStorageInterface $storage - * @param array $scopes - * @param UriInterface $baseApiUri - * - * @return ServiceInterface - * - * @throws Exception - */ - private function buildV1Service( - $serviceName, - CredentialsInterface $credentials, - TokenStorageInterface $storage, - $scopes, - UriInterface $baseApiUri = null - ) { - if (!empty($scopes)) { - throw new Exception( - 'Scopes passed to ServiceFactory::createService but an OAuth1 service was requested.' - ); - } - - return new $serviceName($credentials, $this->httpClient, $storage, new Signature($credentials), $baseApiUri); - } -} diff --git a/vendor/lusitanian/oauth/src/OAuth/bootstrap.php b/vendor/lusitanian/oauth/src/OAuth/bootstrap.php deleted file mode 100644 index 548678a..0000000 --- a/vendor/lusitanian/oauth/src/OAuth/bootstrap.php +++ /dev/null @@ -1,13 +0,0 @@ -register(); From 518d7631a4479f0ed4df29f958288a0eec167d4a Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 8 Feb 2016 09:55:55 +0100 Subject: [PATCH 06/68] Code cleanup Drop useless ControllerInterface Clear most PHPStorm PSR linting --- classes/Controller.php | 32 +++++-- classes/ControllerInterface.php | 16 ---- classes/Login.php | 76 ++++++++++----- classes/LoginController.php | 22 ++++- classes/Utils.php | 5 + login.php | 159 +++++++++++++++++++------------- 6 files changed, 192 insertions(+), 118 deletions(-) delete mode 100644 classes/ControllerInterface.php diff --git a/classes/Controller.php b/classes/Controller.php index 2c82d28..84fd32b 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -2,13 +2,18 @@ namespace Grav\Plugin\Login; +use Grav\Common\Config\Config; use Grav\Common\Grav; -use Grav\Common\Utils; use Grav\Plugin\Login\RememberMe; use Birke\Rememberme\Cookie; +use RocketTheme\Toolbox\Session\Message; -class Controller implements ControllerInterface +/** + * Class Controller + * @package Grav\Plugin\Login + */ +class Controller { /** * @var \Grav\Common\Grav @@ -54,7 +59,7 @@ public function __construct(Grav $grav, $action, $post = null) { $this->grav = $grav; $this->action = $action; - $this->login = isset($this->grav['login'])?$this->grav['login']:''; + $this->login = isset($this->grav['login']) ? $this->grav['login'] : ''; $this->post = $this->getPost($post); $this->rememberMe(); @@ -79,7 +84,7 @@ public function execute() } try { - $success = call_user_func(array($this, $method)); + $success = call_user_func([$this, $method]); } catch (\RuntimeException $e) { $this->setMessage($e->getMessage(), 'error'); } @@ -98,21 +103,24 @@ public function redirect() { if ($this->redirect) { $this->grav->redirect($this->redirect, $this->redirectCode); - } else if ($redirect = $this->grav['config']->get('plugins.login.redirect')) { - $this->grav->redirect($redirect, $this->redirectCode); + } else { + $redirect = $this->grav['config']->get('plugins.login.redirect'); + if ($redirect) { + $this->grav->redirect($redirect, $this->redirectCode); + } } } /** * Set redirect. * - * @param $path + * @param $path * @param int $code */ public function setRedirect($path, $code = 303) { $this->redirect = $path; - $this->code = $code; + $this->redirectCode = $code; } /** @@ -131,9 +139,9 @@ public function setMessage($msg, $type = 'info') /** * Gets and sets the RememberMe class * - * @param mixed $var A rememberMe instance to set + * @param mixed $var A rememberMe instance to set * - * @return Authenticator Returns the current rememberMe instance + * @return RememberMe\RememberMe Returns the current rememberMe instance */ public function rememberMe($var = null) { @@ -168,6 +176,7 @@ public function rememberMe($var = null) * Prepare and return POST data. * * @param array $post + * * @return array */ protected function &getPost($post) @@ -179,6 +188,7 @@ protected function &getPost($post) $post = array_merge_recursive($post, $this->jsonDecode($post['_json'])); unset($post['_json']); } + return $post; } @@ -186,6 +196,7 @@ protected function &getPost($post) * Recursively JSON decode data. * * @param array $data + * * @return array */ protected function jsonDecode(array $data) @@ -197,6 +208,7 @@ protected function jsonDecode(array $data) $value = json_decode($value, true); } } + return $data; } } diff --git a/classes/ControllerInterface.php b/classes/ControllerInterface.php deleted file mode 100644 index a80e14d..0000000 --- a/classes/ControllerInterface.php +++ /dev/null @@ -1,16 +0,0 @@ -grav = $grav; @@ -24,10 +34,10 @@ public function __construct(Grav $grav) //$this->route = $route; $this->session = $this->grav['session']; $this->user = $this->grav['user']; - + $this->uri = $this->grav['uri']; } - + /** * Add message into the session queue. * @@ -40,7 +50,7 @@ public function setMessage($msg, $type = 'info') $messages = $this->grav['messages']; $messages->add($msg, $type); } - + /** * Fetch and delete messages from the session queue. * @@ -55,7 +65,7 @@ public function messages($type = null) return $messages->fetch($type); } - + /** * Authenticate user. * @@ -85,7 +95,8 @@ public function authenticate($form) /** @var Grav $grav */ $grav = $this->grav; - $this->setMessage($this->grav['language']->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN', [$this->user->language]), 'info'); + $this->setMessage($this->grav['language']->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN', + [$this->user->language]), 'info'); $redirect_route = $this->uri->route(); $grav->redirect($redirect_route); @@ -115,7 +126,7 @@ public function authorize($action = 'admin.login') return false; } - + /** * Create a new user file * @@ -128,13 +139,15 @@ public function register($data) // Create user object and save it $user = new User($data); $username = $data['username']; - $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, + true, true)); $user->file($file); $user->save(); $user = User::load($username); - if ($data['state'] == 'enabled' && - $this->config->get('plugins.login.user_registration.options.login_after_registration', false)) { + if ($data['state'] == 'enabled' && $this->config->get('plugins.login.user_registration.options.login_after_registration', + false) + ) { //Login user $this->grav['session']->user = $user; @@ -154,15 +167,18 @@ public function register($data) } } - if ($redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration', false)) { + $redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration', false); + if ($redirect) { $this->grav->redirect($redirect); } } - - + + /** * Handle the email to notificate the user account creation to the site admin. * + * @param $user + * * @return bool True if the action was performed. */ public function sendNotificationEmail($user) @@ -174,7 +190,12 @@ public function sendNotificationEmail($user) $sitename = $this->grav['config']->get('site.title', 'Website'); $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.NOTIFICATION_EMAIL_SUBJECT', $sitename]); - $content = $this->grav['language']->translate(['PLUGIN_LOGIN.NOTIFICATION_EMAIL_BODY', $sitename, $user->username, $user->email]); + $content = $this->grav['language']->translate([ + 'PLUGIN_LOGIN.NOTIFICATION_EMAIL_BODY', + $sitename, + $user->username, + $user->email + ]); $to = $this->grav['config']->get('plugins.email.from'); if (empty($to)) { @@ -193,6 +214,8 @@ public function sendNotificationEmail($user) /** * Handle the email to welcome the new user * + * @param $user + * * @return bool True if the action was performed. */ public function sendWelcomeEmail($user) @@ -219,6 +242,8 @@ public function sendWelcomeEmail($user) /** * Handle the email to activate the user account. * + * @param User $user + * * @return bool True if the action was performed. */ protected function sendActivationEmail($user) @@ -235,10 +260,15 @@ protected function sendActivationEmail($user) $param_sep = $this->grav['config']->get('system.param_sep', ':'); $activation_link = $this->grav['base_url_absolute'] . $this->config->get('plugins.login.route_activate') . '/token' . $param_sep . $token . '/username' . $param_sep . $user->username . '/nonce' . $param_sep . Utils::getNonce('user-activation'); - $sitename = $this->grav['config']->get('site.title', 'Website'); + $site_name = $this->grav['config']->get('site.title', 'Website'); - $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_SUBJECT', $sitename]); - $content = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY', $user->username, $activation_link, $sitename]); + $subject = $this->grav['language']->translate(['PLUGIN_LOGIN.ACTIVATION_EMAIL_SUBJECT', $site_name]); + $content = $this->grav['language']->translate([ + 'PLUGIN_LOGIN.ACTIVATION_EMAIL_BODY', + $user->username, + $activation_link, + $site_name + ]); $to = $user->email; $sent = LoginUtils::sendEmail($subject, $content, $to); diff --git a/classes/LoginController.php b/classes/LoginController.php index c37b7ec..70e6f13 100644 --- a/classes/LoginController.php +++ b/classes/LoginController.php @@ -1,14 +1,15 @@ grav['Email'])) { $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); $this->setRedirect('/'); + return true; } if (!$user || !$user->exists()) { $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error'); $this->setRedirect('/forgot'); + return true; } if (empty($user->email)) { - $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), 'error'); + $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), + 'error'); $this->setRedirect('/forgot'); + return true; } @@ -114,6 +119,7 @@ protected function taskForgot() if (empty($from)) { $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); $this->setRedirect('/forgot'); + return true; } @@ -131,6 +137,7 @@ protected function taskForgot() } $this->setRedirect('/'); + return true; } @@ -158,6 +165,7 @@ public function taskReset() if (time() > $expire) { $messages->add($language->translate('PLUGIN_ADMIN.RESET_LINK_EXPIRED'), 'error'); $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); + return true; } @@ -171,12 +179,14 @@ public function taskReset() $messages->add($language->translate('PLUGIN_ADMIN.RESET_PASSWORD_RESET'), 'info'); $this->grav->redirect('/'); + return true; } } $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); + return true; } else { @@ -186,6 +196,7 @@ public function taskReset() if (empty($user) || empty($token)) { $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); + return true; } } @@ -197,6 +208,7 @@ public function taskReset() * Authenticate user. * * @param array $form Form fields. + * * @return bool */ protected function authenticate($form) diff --git a/classes/Utils.php b/classes/Utils.php index ab47ee3..f12a3a6 100644 --- a/classes/Utils.php +++ b/classes/Utils.php @@ -4,11 +4,16 @@ use Grav\Common\Grav; +/** + * Class Utils + * @package Grav\Plugin\Login + */ class Utils { /** * Handle sending an email. * + * @param $subject * @param string $content * @param string $to * diff --git a/login.php b/login.php index 850c636..adbdac9 100644 --- a/login.php +++ b/login.php @@ -2,16 +2,22 @@ namespace Grav\Plugin; use Grav\Plugin\Admin; -use Grav\Common\File\CompiledYamlFile; -use Grav\Common\Plugin; +use Grav\Common\Grav; +use Grav\Common\Language\Language; use Grav\Common\Page\Page; +use Grav\Common\Page\Pages; +use Grav\Common\Plugin; +use Grav\Common\Twig\Twig; use Grav\Common\User\User; use Grav\Common\Utils; -use Grav\Plugin\Login\Utils as LoginUtils; - +use Grav\Common\Uri; use RocketTheme\Toolbox\Event\Event; use RocketTheme\Toolbox\Session\Message; +/** + * Class LoginPlugin + * @package Grav\Plugin + */ class LoginPlugin extends Plugin { /** @@ -39,6 +45,11 @@ class LoginPlugin extends Plugin */ protected $authorized = true; + /** + * @var bool + */ + protected $login; + /** * @return array */ @@ -46,14 +57,14 @@ public static function getSubscribedEvents() { return [ 'onPluginsInitialized' => ['initialize', 10000], - 'onTask.login.login' => ['loginController', 0], - 'onTask.login.forgot' => ['loginController', 0], - 'onTask.login.logout' => ['loginController', 0], - 'onTask.login.reset' => ['loginController', 0], - 'onPageInitialized' => ['authorizePage', 0], - 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0], - 'onTwigSiteVariables' => ['onTwigSiteVariables', -100000], - 'onFormProcessed' => ['onFormProcessed', 0] + 'onTask.login.login' => ['loginController', 0], + 'onTask.login.forgot' => ['loginController', 0], + 'onTask.login.logout' => ['loginController', 0], + 'onTask.login.reset' => ['loginController', 0], + 'onPageInitialized' => ['authorizePage', 0], + 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0], + 'onTwigSiteVariables' => ['onTwigSiteVariables', -100000], + 'onFormProcessed' => ['onFormProcessed', 0] ]; } @@ -70,16 +81,13 @@ public function initialize() throw new \RuntimeException('The Login plugin requires "system.session" to be enabled'); } - /** @var Grav\Common\Session */ - $session = $this->grav['session']; - // Autoload classes $autoload = __DIR__ . '/vendor/autoload.php'; if (!is_file($autoload)) { throw new \Exception('Login Plugin failed to load. Composer dependencies not met.'); } require_once $autoload; - + // Define session message service. $this->grav['messages'] = function ($c) { $session = $c['session']; @@ -90,9 +98,11 @@ public function initialize() return $session->messages; }; - + // Define current user service. $this->grav['user'] = function ($c) { + /** @var Grav $c */ + $session = $c['session']; if (!isset($session->user)) { @@ -126,12 +136,12 @@ public function initialize() return $session->user; }; - - + + //Initialize Login Object require_once __DIR__ . '/classes/Login.php'; - $this->login = new Login($this->grav); - + $this->login = new \Grav\Plugin\Login\Login($this->grav); + //Store Login Object in Grav $this->grav['login'] = $this->login; @@ -277,6 +287,7 @@ public function handleUserActivation() $message = $this->grav['language']->translate('PLUGIN_LOGIN.INVALID_REQUEST'); $messages->add($message, 'error'); $this->grav->redirect('/'); + return; } @@ -338,26 +349,40 @@ public function loginController() if (method_exists('Grav\Common\Utils', 'getNonce')) { if ($task == 'login') { if (!isset($post['login-form-nonce']) || !Utils::verifyNonce($post['login-form-nonce'], 'login-form')) { - $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info'); + $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), + 'info'); $this->authenticated = false; $twig = $this->grav['twig']; $twig->twig_vars['notAuthorized'] = true; + return; } - } else if ($task == 'logout') { - $nonce = $this->grav['uri']->param('logout-nonce'); - if (!isset($nonce) || !Utils::verifyNonce($nonce, 'logout-form')) { - return; - } - } else if ($task == 'forgot') { - if (!isset($post['forgot-form-nonce']) || !Utils::verifyNonce($post['forgot-form-nonce'], 'forgot-form')) { - $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info'); - return; - } - } else if ($task == 'reset') { - if (!isset($post['reset-form-nonce']) || !Utils::verifyNonce($post['reset-form-nonce'], 'reset-form')) { - //$this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info'); - //return; + } else { + if ($task == 'logout') { + $nonce = $this->grav['uri']->param('logout-nonce'); + if (!isset($nonce) || !Utils::verifyNonce($nonce, 'logout-form')) { + return; + } + } else { + if ($task == 'forgot') { + if (!isset($post['forgot-form-nonce']) || !Utils::verifyNonce($post['forgot-form-nonce'], + 'forgot-form') + ) { + $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), + 'info'); + + return; + } + } else { + if ($task == 'reset') { + if (!isset($post['reset-form-nonce']) || !Utils::verifyNonce($post['reset-form-nonce'], + 'reset-form') + ) { + //$this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info'); + //return; + } + } + } } } } @@ -384,20 +409,20 @@ public function authorizePage() } $header = $page->header(); - $rules = isset($header->access) ? (array) $header->access : []; + $rules = isset($header->access) ? (array)$header->access : []; $config = $this->mergeConfig($page); if ($config->get('parent_acl')) { - // If page has no ACL rules, use its parent's rules - if (!$rules) { - $parent = $page->parent(); - while (!$rules and $parent) { - $header = $parent->header(); - $rules = isset($header->access) ? (array) $header->access : []; - $parent = $parent->parent(); + // If page has no ACL rules, use its parent's rules + if (!$rules) { + $parent = $page->parent(); + while (!$rules and $parent) { + $header = $parent->header(); + $rules = isset($header->access) ? (array)$header->access : []; + $parent = $parent->parent(); + } } - } } // Continue to the page if it has no ACL rules. @@ -463,11 +488,8 @@ public function onTwigSiteVariables() { /** @var Twig $twig */ $twig = $this->grav['twig']; - - $this->grav->fireEvent('onLoginPage'); - /** @var User $user */ - $user = $this->grav['user']; + $this->grav->fireEvent('onLoginPage'); $extension = $this->grav['uri']->extension(); $extension = $extension ?: 'html'; @@ -525,23 +547,28 @@ public function onFormProcessed(Event $event) $data['username'] = $username; if (file_exists($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT))) { - $this->grav->fireEvent('onFormValidationError', - new Event([ - 'form' => $form, - 'message' => $this->grav['language']->translate(['PLUGIN_LOGIN.USERNAME_NOT_AVAILABLE', $username]) + $this->grav->fireEvent('onFormValidationError', new Event([ + 'form' => $form, + 'message' => $this->grav['language']->translate([ + 'PLUGIN_LOGIN.USERNAME_NOT_AVAILABLE', + $username + ]) ])); $event->stopPropagation(); + return; } - if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', false)) { + if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', + false) + ) { if ($form->value('password1') != $form->value('password2')) { - $this->grav->fireEvent('onFormValidationError', - new Event([ - 'form' => $form, + $this->grav->fireEvent('onFormValidationError', new Event([ + 'form' => $form, 'message' => $this->grav['language']->translate('PLUGIN_LOGIN.PASSWORDS_DO_NOT_MATCH') ])); $event->stopPropagation(); + return; } $data['password'] = $form->value('password1'); @@ -549,14 +576,16 @@ public function onFormProcessed(Event $event) $fields = $this->config->get('plugins.login.user_registration.fields', []); - foreach($fields as $field) { + foreach ($fields as $field) { // Process value of field if set in the page process.register_user $default_values = $this->config->get('plugins.login.user_registration.default_values'); - if ($default_values) foreach($default_values as $key => $param) { - $values = explode(',', $param); + if ($default_values) { + foreach ($default_values as $key => $param) { + $values = explode(',', $param); - if ($key == $field) { - $data[$field] = $values; + if ($key == $field) { + $data[$field] = $values; + } } } @@ -565,7 +594,9 @@ public function onFormProcessed(Event $event) } } - if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', false)) { + if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', + false) + ) { unset($data['password1']); unset($data['password2']); } @@ -576,7 +607,7 @@ public function onFormProcessed(Event $event) } else { $data['state'] = 'enabled'; } - + $this->login->register($data); break; } From 9953fc50fbc12741b7d6f0c38f828c94ba939e83 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 8 Feb 2016 10:18:22 +0100 Subject: [PATCH 07/68] Use a single controller --- classes/Controller.php | 241 +++++++++++++++++++++++++++++++++- classes/LoginController.php | 254 ------------------------------------ login.php | 10 +- 3 files changed, 245 insertions(+), 260 deletions(-) delete mode 100644 classes/LoginController.php diff --git a/classes/Controller.php b/classes/Controller.php index 84fd32b..512779f 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -5,6 +5,10 @@ use Grav\Common\Config\Config; use Grav\Common\Grav; use Grav\Plugin\Login\RememberMe; +use Grav\Common\Language\Language; +use Grav\Common\User\User; +use Grav\Common\Utils; +use Grav\Plugin\Login\Utils as LoginUtils; use Birke\Rememberme\Cookie; use RocketTheme\Toolbox\Session\Message; @@ -43,7 +47,7 @@ class Controller /** * @var string */ - protected $prefix = 'do'; + protected $prefix = 'task'; /** * @var \Birke\Rememberme\Authenticator @@ -96,6 +100,241 @@ public function execute() return $success; } + /** + * Handle login. + * + * @return bool True if the action was performed. + */ + public function taskLogin() + { + $t = $this->grav['language']; + if ($this->authenticate($this->post)) { + $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); + $referrer = $this->grav['uri']->referrer('/'); + $this->setRedirect($referrer); + } else { + $user = $this->grav['user']; + if ($user->username) { + $this->setMessage($t->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'error'); + } else { + $this->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_FAILED'), 'error'); + } + } + + return true; + } + + /** + * Handle logout. + * + * @return bool True if the action was performed. + */ + public function taskLogout() + { + /** @var User $user */ + $user = $this->grav['user']; + + if (!$this->rememberMe->login()) { + $credentials = $user->get('username'); + $this->rememberMe->getStorage()->cleanAllTriplets($credentials); + } + $this->rememberMe->clearCookie(); + + $this->grav['session']->invalidate()->start(); + $this->setRedirect('/'); + + return true; + } + + /** + * Handle the email password recovery procedure. + * + * @return bool True if the action was performed. + */ + protected function taskForgot() + { + $param_sep = $this->grav['config']->get('system.param_sep', ':'); + $data = $this->post; + + $username = isset($data['username']) ? $data['username'] : ''; + $user = !empty($username) ? User::load($username) : null; + + /** @var Language $l */ + $language = $this->grav['language']; + $messages = $this->grav['messages']; + + if (!isset($this->grav['Email'])) { + $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $this->setRedirect('/'); + + return true; + } + + if (!$user || !$user->exists()) { + $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error'); + $this->setRedirect('/forgot'); + + return true; + } + + if (empty($user->email)) { + $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), + 'error'); + $this->setRedirect('/forgot'); + + return true; + } + + $token = md5(uniqid(mt_rand(), true)); + $expire = time() + 604800; // next week + + $user->reset = $token . '::' . $expire; + $user->save(); + + $author = $this->grav['config']->get('site.author.name', ''); + $fullname = $user->fullname ?: $username; + + $reset_link = $this->grav['base_url_absolute'] . $this->grav['config']->get('plugins.login.route_reset') . '/task:login.reset/token' . $param_sep . $token . '/user' . $param_sep . $username . '/nonce' . $param_sep . Utils::getNonce('reset-form'); + + $sitename = $this->grav['config']->get('site.title', 'Website'); + $from = $this->grav['config']->get('plugins.email.from'); + + if (empty($from)) { + $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $this->setRedirect('/forgot'); + + return true; + } + + $to = $user->email; + + $subject = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_SUBJECT', $sitename]); + $content = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_BODY', $fullname, $reset_link, $author, $sitename]); + + $sent = LoginUtils::sendEmail($subject, $content, $to); + + if ($sent < 1) { + $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_FAILED_TO_EMAIL'), 'error'); + } else { + $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL', $to]), 'info'); + } + + $this->setRedirect('/'); + + return true; + } + + /** + * Handle the reset password action. + * + * @return bool True if the action was performed. + */ + public function taskReset() + { + $data = $this->post; + $language = $this->grav['language']; + $messages = $this->grav['messages']; + + if (isset($data['password'])) { + $username = isset($data['username']) ? $data['username'] : null; + $user = !empty($username) ? User::load($username) : null; + $password = isset($data['password']) ? $data['password'] : null; + $token = isset($data['token']) ? $data['token'] : null; + + if (!empty($user) && $user->exists() && !empty($user->reset)) { + list($good_token, $expire) = explode('::', $user->reset); + + if ($good_token === $token) { + if (time() > $expire) { + $messages->add($language->translate('PLUGIN_ADMIN.RESET_LINK_EXPIRED'), 'error'); + $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); + + return true; + } + + unset($user->hashed_password); + unset($user->reset); + $user->password = $password; + + $user->validate(); + $user->filter(); + $user->save(); + + $messages->add($language->translate('PLUGIN_ADMIN.RESET_PASSWORD_RESET'), 'info'); + $this->grav->redirect('/'); + + return true; + } + } + + $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); + $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); + + return true; + + } else { + $user = $this->grav['uri']->param('user'); + $token = $this->grav['uri']->param('token'); + + if (empty($user) || empty($token)) { + $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); + $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); + + return true; + } + } + + return true; + } + + /** + * Authenticate user. + * + * @param array $form Form fields. + * + * @return bool + */ + protected function authenticate($form) + { + /** @var User $user */ + $user = $this->grav['user']; + + if (!$user->authenticated) { + $username = isset($form['username']) ? $form['username'] : $this->rememberMe->login(); + + // Normal login process + $user = User::load($username); + if ($user->exists()) { + if (!empty($form['username']) && !empty($form['password'])) { + // Authenticate user. + $user->authenticated = $user->authenticate($form['password']); + + if ($user->authenticated) { + $this->grav['session']->user = $user; + + unset($this->grav['user']); + $this->grav['user'] = $user; + + // If the user wants to be remembered, create + // Rememberme cookie + if (!empty($form['rememberme'])) { + $this->rememberMe->createCookie($form['username']); + } else { + $this->rememberMe->clearCookie(); + $this->rememberMe->getStorage()->cleanAllTriplets($user->get('username')); + } + } + } + } + } + + // Authorize against user ACL + $user_authorized = $user->authorize('site.login'); + $user->authenticated = ($user->authenticated && $user_authorized); + + return $user->authenticated; + } + /** * Redirects an action */ diff --git a/classes/LoginController.php b/classes/LoginController.php deleted file mode 100644 index 70e6f13..0000000 --- a/classes/LoginController.php +++ /dev/null @@ -1,254 +0,0 @@ -grav['language']; - if ($this->authenticate($this->post)) { - $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); - $referrer = $this->grav['uri']->referrer('/'); - $this->setRedirect($referrer); - } else { - $user = $this->grav['user']; - if ($user->username) { - $this->setMessage($t->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'error'); - } else { - $this->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_FAILED'), 'error'); - } - } - - return true; - } - - /** - * Handle logout. - * - * @return bool True if the action was performed. - */ - public function taskLogout() - { - /** @var User $user */ - $user = $this->grav['user']; - - if (!$this->rememberMe->login()) { - $credentials = $user->get('username'); - $this->rememberMe->getStorage()->cleanAllTriplets($credentials); - } - $this->rememberMe->clearCookie(); - - $this->grav['session']->invalidate()->start(); - $this->setRedirect('/'); - - return true; - } - - /** - * Handle the email password recovery procedure. - * - * @return bool True if the action was performed. - */ - protected function taskForgot() - { - $param_sep = $this->grav['config']->get('system.param_sep', ':'); - $data = $this->post; - - $username = isset($data['username']) ? $data['username'] : ''; - $user = !empty($username) ? User::load($username) : null; - - /** @var Language $l */ - $language = $this->grav['language']; - $messages = $this->grav['messages']; - - if (!isset($this->grav['Email'])) { - $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); - $this->setRedirect('/'); - - return true; - } - - if (!$user || !$user->exists()) { - $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error'); - $this->setRedirect('/forgot'); - - return true; - } - - if (empty($user->email)) { - $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), - 'error'); - $this->setRedirect('/forgot'); - - return true; - } - - $token = md5(uniqid(mt_rand(), true)); - $expire = time() + 604800; // next week - - $user->reset = $token . '::' . $expire; - $user->save(); - - $author = $this->grav['config']->get('site.author.name', ''); - $fullname = $user->fullname ?: $username; - - $reset_link = $this->grav['base_url_absolute'] . $this->grav['config']->get('plugins.login.route_reset') . '/task:login.reset/token' . $param_sep . $token . '/user' . $param_sep . $username . '/nonce' . $param_sep . Utils::getNonce('reset-form'); - - $sitename = $this->grav['config']->get('site.title', 'Website'); - $from = $this->grav['config']->get('plugins.email.from'); - - if (empty($from)) { - $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); - $this->setRedirect('/forgot'); - - return true; - } - - $to = $user->email; - - $subject = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_SUBJECT', $sitename]); - $content = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_BODY', $fullname, $reset_link, $author, $sitename]); - - $sent = LoginUtils::sendEmail($subject, $content, $to); - - if ($sent < 1) { - $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_FAILED_TO_EMAIL'), 'error'); - } else { - $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL', $to]), 'info'); - } - - $this->setRedirect('/'); - - return true; - } - - /** - * Handle the reset password action. - * - * @return bool True if the action was performed. - */ - public function taskReset() - { - $data = $this->post; - $language = $this->grav['language']; - $messages = $this->grav['messages']; - - if (isset($data['password'])) { - $username = isset($data['username']) ? $data['username'] : null; - $user = !empty($username) ? User::load($username) : null; - $password = isset($data['password']) ? $data['password'] : null; - $token = isset($data['token']) ? $data['token'] : null; - - if (!empty($user) && $user->exists() && !empty($user->reset)) { - list($good_token, $expire) = explode('::', $user->reset); - - if ($good_token === $token) { - if (time() > $expire) { - $messages->add($language->translate('PLUGIN_ADMIN.RESET_LINK_EXPIRED'), 'error'); - $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); - - return true; - } - - unset($user->hashed_password); - unset($user->reset); - $user->password = $password; - - $user->validate(); - $user->filter(); - $user->save(); - - $messages->add($language->translate('PLUGIN_ADMIN.RESET_PASSWORD_RESET'), 'info'); - $this->grav->redirect('/'); - - return true; - } - } - - $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); - $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); - - return true; - - } else { - $user = $this->grav['uri']->param('user'); - $token = $this->grav['uri']->param('token'); - - if (empty($user) || empty($token)) { - $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); - $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); - - return true; - } - } - - return true; - } - - /** - * Authenticate user. - * - * @param array $form Form fields. - * - * @return bool - */ - protected function authenticate($form) - { - /** @var User $user */ - $user = $this->grav['user']; - - if (!$user->authenticated) { - $username = isset($form['username']) ? $form['username'] : $this->rememberMe->login(); - - // Normal login process - $user = User::load($username); - if ($user->exists()) { - if (!empty($form['username']) && !empty($form['password'])) { - // Authenticate user. - $user->authenticated = $user->authenticate($form['password']); - - if ($user->authenticated) { - $this->grav['session']->user = $user; - - unset($this->grav['user']); - $this->grav['user'] = $user; - - // If the user wants to be remembered, create - // Rememberme cookie - if (!empty($form['rememberme'])) { - $this->rememberMe->createCookie($form['username']); - } else { - $this->rememberMe->clearCookie(); - $this->rememberMe->getStorage()->cleanAllTriplets($user->get('username')); - } - } - } - } - } - - // Authorize against user ACL - $user_authorized = $user->authorize('site.login'); - $user->authenticated = ($user->authenticated && $user_authorized); - - return $user->authenticated; - } -} diff --git a/login.php b/login.php index adbdac9..778a9f3 100644 --- a/login.php +++ b/login.php @@ -11,6 +11,8 @@ use Grav\Common\User\User; use Grav\Common\Utils; use Grav\Common\Uri; +use Grav\Plugin\Login\Login; +use Grav\Plugin\Login\Controller; use RocketTheme\Toolbox\Event\Event; use RocketTheme\Toolbox\Session\Message; @@ -109,7 +111,7 @@ public function initialize() $session->user = new User; if ($c['config']->get('plugins.login.rememberme.enabled')) { - $controller = new Login\Controller($c, ''); + $controller = new Controller($c, ''); $rememberMe = $controller->rememberMe(); // If we can present the correct tokens from the cookie, we are logged in @@ -137,10 +139,8 @@ public function initialize() return $session->user; }; - //Initialize Login Object - require_once __DIR__ . '/classes/Login.php'; - $this->login = new \Grav\Plugin\Login\Login($this->grav); + $this->login = new Login($this->grav); //Store Login Object in Grav $this->grav['login'] = $this->login; @@ -387,7 +387,7 @@ public function loginController() } } - $controller = new Login\LoginController($this->grav, $task, $post); + $controller = new Controller($this->grav, $task, $post); $controller->execute(); $controller->redirect(); } From 42dd44d5980105b7207af6cb5c586f8d9d55fcc1 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 8 Feb 2016 10:31:51 +0100 Subject: [PATCH 08/68] More linting --- classes/Controller.php | 5 ++--- classes/Login.php | 14 ++++++++++---- login.php | 24 ++++++------------------ 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/classes/Controller.php b/classes/Controller.php index 512779f..01b4e6a 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -306,7 +306,7 @@ protected function authenticate($form) $user = User::load($username); if ($user->exists()) { if (!empty($form['username']) && !empty($form['password'])) { - // Authenticate user. + // Authenticate user $user->authenticated = $user->authenticate($form['password']); if ($user->authenticated) { @@ -315,8 +315,7 @@ protected function authenticate($form) unset($this->grav['user']); $this->grav['user'] = $user; - // If the user wants to be remembered, create - // Rememberme cookie + // If the user wants to be remembered, create Rememberme cookie if (!empty($form['rememberme'])) { $this->rememberMe->createCookie($form['username']); } else { diff --git a/classes/Login.php b/classes/Login.php index 07c49ac..06a8131 100644 --- a/classes/Login.php +++ b/classes/Login.php @@ -1,27 +1,33 @@ Date: Mon, 8 Feb 2016 11:28:34 +0100 Subject: [PATCH 09/68] Drop assets --- assets/github/github.png | Bin 43302 -> 0 bytes assets/github/github_2.png | Bin 57285 -> 0 bytes assets/github/github_3.png | Bin 62010 -> 0 bytes assets/google/google.png | Bin 33180 -> 0 bytes assets/google/google_2.png | Bin 79910 -> 0 bytes assets/google/google_3.png | Bin 77577 -> 0 bytes assets/google/google_4.png | Bin 62290 -> 0 bytes assets/google/google_5.png | Bin 43359 -> 0 bytes assets/google/google_6.png | Bin 100046 -> 0 bytes assets/google/google_7.png | Bin 60169 -> 0 bytes assets/google/google_8.png | Bin 45853 -> 0 bytes 11 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 assets/github/github.png delete mode 100644 assets/github/github_2.png delete mode 100644 assets/github/github_3.png delete mode 100644 assets/google/google.png delete mode 100644 assets/google/google_2.png delete mode 100644 assets/google/google_3.png delete mode 100644 assets/google/google_4.png delete mode 100644 assets/google/google_5.png delete mode 100644 assets/google/google_6.png delete mode 100644 assets/google/google_7.png delete mode 100644 assets/google/google_8.png diff --git a/assets/github/github.png b/assets/github/github.png deleted file mode 100644 index a8595d84ae4f0b29663f212ba00357b3c0031918..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43302 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 diff --git a/assets/github/github_3.png b/assets/github/github_3.png deleted file mode 100644 index ee9fd765e29e3e98c94ee612ecb8d577f4fc3ca1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62010 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 diff --git a/assets/google/google.png b/assets/google/google.png deleted file mode 100644 index 189c490355be31ceb4f1230e3088bab64a8789b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33180 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

jSMq{(La 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 TOA1(u-rijvZk0QZefz%vyEscJ diff --git a/assets/google/google_2.png b/assets/google/google_2.png deleted file mode 100644 index 0d2b116663a2b71c1b9f4721a891bbd86f5a3ec6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79910 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 KnS0OR<^KW#=pqIH diff --git a/assets/google/google_4.png b/assets/google/google_4.png deleted file mode 100644 index bba73058769fe011be6dca94d494216704d382ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62290 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 diff --git a/assets/google/google_5.png b/assets/google/google_5.png deleted file mode 100644 index 966e45d2d78ccbbaad635d61433c69606aeb28ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43359 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�rv>xRACSyegE4P{Nmmll zbCHwLAhmwMb#z2%#p;0%C#CSuR|W>p&)A%)EhqxEa!H|tx@SczUS(l7SGeQpYO8Bi zE%o-ZN5>DAz&}^d_T6XjA3gd0P!!Whjj6REX~OPCfnqgzWFJk+90!Ah_|RsdsbE1) zxoGF5Z-%x;F0>)zKB9#?)NNmmUfR_jjh61Bt4a+JUSsuJ3R7#<51*Vz`Ay2%-2zK=Ds7QjP*Bg_i zC_(X;R4VW;Jj}gZMGE!nd^hu+yu)k4b&4MP_)pMVL@lVqQ zX0I;Ht{sX{v34v$abp?Y!x0Vsma}fL+hDQ)r)z%8)J=cMNF!2JCAp*h-moo(d~jy^ zs$pUZ6d51j!_D4odLs0;yg1B|85^Q>zQrakycSnw_+`TNEoI1D#J(u6+=0<%t~Ru* zS>SRD-9Bc=duvysyg}>HTIOqicgc+`MkeiKe3R(=tMj$tvp!m(v_DwG0ueuN6iUn| zTWvRXN!t59oJUks-!7|Z;PKnM);{O0OV}0tA*|cpe4ZEPTCF{WI%O-m(vgf}{*x0; z^;5h0jPiaphC<_|w~!yNaD_|L?wJ*AH6yo#GVf!Ib14;=>1c?LKx(ot5N=icli)0f zxull$rz{hAX{ULQ*IOz~RtQC*OE|(T4##fm5@ye-kA73naCBj$F+%ce_u2#NOfG3i zOU)O}wih+UQ^MT`we2c9{qXt+d_bCjKlOP&8g&_+@55`1`hW>Ipa5t7j zHQ2PEPmd7VJw48GUj3_O=! zI}|~Y)ct9pCN63vN|FM1Y6^rqr>`ns9Te}2wyHnTVQqE&s*1e#fMm7*^Se)}b)vnN zt-AO>6`WgdIGm_fO9g|X>*+NVCSG4hH^U+>l)Ob&QwJeENKAVLJr^W?Ph`io{j(U6 zBm*AEf`J$u2oH|;Df0uuwYoy}%yc$!$C#=xh&&X~=St1Y2Pzx#< zOIFMfQOB?8n)u``bW!?pQM0OLKkFV{VnthJFP1)jf;Y+`(zOfQ4Zy3Oxz|yI@DCeV z!>kgwuC1#Zc6oW(Hg3$`<8ERfbva`TLlf4#IKFrNd6aUdzFwy~JTw%wi1RGa1yeg* zmJ7sfFtjWyxL|3D*LmB4&qe;EGp_|NAvM{A$PK0B=hPLg%9yp1xG?K!<#p);_PK0v zlT3>6l_+=uiO2*OT;W#he=*K$4mDJYBhBs^B$&uc(i#HIP3=qxP&_=m7OP9@6tp4k z9y!+iGFg3$1f2hEF$KfsN-8Q2T>4aj@T8*ML4T&b_8xei3dDdX$=^6ywEALya&}h7 z@D_}HgG-OerKjswlmY@vwyS5GuOdTyi7becILWy8SyM&r6$=`qyH`{F_pANo8?8%NYo9tyWihf14h=;PF;!Gl5Tq-~ zOg7fmG9Jr#9{s?&k6=INa+`SehJ}??WOM5B;*-%g0Yb3Eo;D>lQ5-mzyqM}G=Oe&! zW&ICZ_7$hXdaBnX1}YmWl}RPPH{TEfWTIM4%g{p94%Vw6kY}+82^hj!7a#=L?#pg3 zk4|G$l$*(SbtOv&hV(53=46fS&ot^$UNDC)o<4R@Ic{mF2}AAWc|8Ada3x@7=c6c* z>D8X0JUHYsUD6MGs&`W4z8;SI0#=deC)9^iaBs8>K)zIQqMa5Th%q#TC)@Frs|i z!ix(7T;&-ek`PB_D$memIbj_^DWKOhB-UNTTqHezaUkHV3 zc2N5CB1^P3(@TD1Q)yV}zNj}jPv(k+Aago{>BT-=UF;?Kiqa}!rqwv2Uhtv}u?>Ow z(jqyi#Mjjqxz+J;Xzo@zQ3>_xX1ni9_H%T!`yXpqM@P$zhRp(@=hP$t`HO*4x>D~* z`&wW?0;Tj$DZP@C8Tmf*p|+||fEb}JLo=5MW~ zR8{dvta>98)PoSpC{Md>gdoqPB_+udx!DZglhcL+df@!>PA9$b12q(YRxA~;y}r9m zodP)uq)jW)WzzXf?saXQg3n_62KZI}6oo+sSK;#m&2d(4rxb#wQa*cy*W{LLqF&^d z@$)zi^JQG9WrrkQ*8!9XzP3eb2B69Hds{tuJ}+;s6c=dLp^vs8Do&DNFz*;&N;;uE z&=;oomAxvu>Pwbhcn|N}ROJ#(X0`I5dIzs2m<_zG=N)Ng&=~`R0?Pk5I*xB4gJK>N zA8)@oybE=Cqfm5!9XV*`R+?j}o zrFrX1r427UU8c(ItYBIY;{b}A^#Na*)Ro!Gu!|=8!UvlPSe2&OGeG^#5w4b);e}M6 zW1*bB)i*Z;9)mqkdcId>TMmHvO~)HFCKfuJ)xB_YIG(F7y2sChFEGa&wus`2kDfr} z>=pigOYeMyI?zoz_c$Jv9bU54VOJjUIQ z7pnZDh^j<3MV&F~d7sXu4}ShYG$%asyYV~{&dv7@psPY62d@n!w(FIkSP5L)2j1)& z)k#(gPwww7e(<<2hO5thm&gx|f})^sM%uYP8~!FUrYfw0M~&VeqjJ)e*RJR@#3gat ziW4bQNWD(aQlIJC)&0=q$4~3`9;LiYIJfhF-YKHbwhTVT&$7f8j3;;G;zo$5%HC8a zRvDo8bfX178^HeU1O2`iwBUuOkKY+pSKy!7+=gyBzZw##`Pk}$KSEHY#NI~;CGjtn z3nDgifZU?0A#X-`uOoZaBnS4GNu4jd6Im5X%`MWLE;pU3h`#ZjZ95_5jY`rFY2;_C zW}K`%PS2nsTKh0q}f5wI*dP^0^&-clSUv%kohcfa>)(N}H33?-Z0_F!nD}=^e0KxgW zkeEu`ou@PqI9++?JOQDPz4D!r}8^sR3PK9lt5f1re?{D$DsXVs40o0X5KIOR+W$viD^dY+s?lkQ zP(;7`1Q*e{%t*bV|FvU(U)i$itG}G`BBWn;s7>;(3c#-%=PxNlr4jxgfA{Zr{BK9~ z-){c@w##C;8-JIpS8QNkQ@X;Na~6j}o#r@OuQtU)WtWj{X|aQfzf?OAGyLsgy=(DM zJ(k-zN2CS)5##o)_RCN*^{K7A9;c-nr!}xn4YciYV}*gCvE^SmE{eY`?#|8O!r@oH z#p{V%v1XbUTBUQ#iw0$Pef!t1rvR>~s~7&=C-v#+*%_ylR5Wn?SgSx-;WT?!OkEf3 zIBrJ*KF{{T<{N#OJml_C+Ze~%>QnlyZXSRTCPtZ-Z!@c=L_`-i6#+YGxIksfcpFaH z*#9tm@Zyw_Hgo>v^mRktIZt5DL29)p3wXBhg=bh!^L+2cV|6A|h1ejUWk*1f0FrhW zFXle-!8;v#A_hX`;G&j`d+|GW@mhtOxY?7 zeT*JFNR}!AJ!FHwMg48`4xA+ZQaUcA5-Qw+-Cy~^FpYczrR1N)bt1m#BK}PkVp?md z%PqcHo1LA6QP5$}ZTi~_n~X_scyf?vD~c{5@bWaOf9_;`7~u0IM}maOAq~n!9=?>` z(Z)|dn~I_bvyst)MMXpae!W;E1_l?w*rx}=w+kc8<@hf|N|IboupetFQKdGy?^vs3 zQ0WE$%ub{P1ao%udU_9}C+I4eH#UzIM=?A>8^cm>&lj(tIXet))KL8^E>Oo0&1!qINyB(##&j5LBlWd+L0(3dr zpM(e{WvUibt&1QMy+J+OoIU8~wW`V1t`9On(0qZ4KZ1h&5&JWhy@u0*ND1oK+apGD z$98k=KHu(3wv?za)E2ay`tx)v^WP8HGu5`iX(fR7i{d~mIk9dwo) zka-=2?sNH{OQUZ&eh-!C}c;*+FY6tr%8;nC?{Mect1JwEPAp`{a{)cyef57}pEW$hr&8W~;<~CD|nyLKug7 zIc8Ipig)I4XXkE7-VsPL!#xeXWoKv>KB4(Phz{mKl|3v)pHW@3V0!AuFYP)g1qrv3 ziH`@}U*j5l9^CXmR9X*ZT^6iHzdeZ`#t>aP_+?FZM2t~cyw4_Vt@-;S4*oo{XZ4*m zUZEgQSn1&wIF`Xm9IEx&Jj!l32~-TpIt6(~IO3f~Wlr>CJoK-t(h{QAJEcJiZFx_h zS44xF<7O)S%?{YFP16!ANe5p$#j=(c&xTP?y0*loD3ds#xd#GgFbw|HMZ z(&h?JNv3XT6<)y8l$D2@HDi>7Z*ALMh*U0%|9SGPSt%L!TcaLmf2EzA$Z80UW5)yH z25JMTobu<@H_oHWJov)o!1eZ~&w*CYVSYs?q9@*sWq}$z$dp$um`(X35&KcR?F-y* zl94j#O2bU6kpcLSOOf@C-k6^^uJ}T1dZ(+d&!g9!Yu{P~!c*zMXM{s7J$kfpnb|XK zn@8t2co$`kt0(S>adE5sFNWTrG4*nliaaT{O?gO%Sawl#L;)x$$yfA+$f;>OD zAHeWT!xcv@MXy#!l(sP+L@>4BWHg-Xt3&h9{n0lEIhzJ};~q8m;fM5E5@g>;W5}sP z7$xGo&EbOFT%rh+;zd7qq?{_m$a=gGRJaQ;Jtz;(Dc0RUm7`V{npu_zjMLLfx=lS# zK&uua;?R^y`sVdW=>4lnC)SqS7zr8+L|Ba9nd&CBZ0(lk?*HM{fz(AWXr3t!p2SO( ziax);PmwQVoq|GGm2>2^aGs&!5JT>B632 zgZHhV&S*;YR9FDUxy6oT#+#*rl`quXbU%;jU{W_8R&GLat+dTn>LJ-o`aF2T<#le~ zy~jC(3a_1-T~ggY1D-3!i~leefYt|GJ$oR@wfDLw5U8tM@ROpY@C-(HBODwF>xQ2N zvCXNTxUgqBvw?sWmtv~Ag`_lmj;4}}2~l8wJPp*3b#>;GH|bo*Y2*g&&-p>lkY@qIT(wADzDfOBHzmP0=2AW&yRIay`4?|JoQWLbP^W{nB;} zM<*Bh0{Wp?VN_Fv;7Vi5t5Y0Y|CU9CT{wvBFnF~@fe1fn$BY%!KA>JkHQKtdbu;jP zSkV_?Mf^SfjJD4k@$0eAYYyv2;x_8f%^`_MFAGRy1~=O;B`5tyHt~-lf*Zsw&iQ~S z>mdD~w5HBuNY6U|+QnhV(yLa|Cn>ya61AntK)^Ec1T&cpDz)eTp5@rEc5P=q@-7p9 zK>h0>T^;}%HvD#g%cVvZY6`gCchLZ=FKCS;rsyZUabL=BFrW?M=TgT#D<9yoR3M<3<=K+TV4$PC01pQA}^&*+*U) z2-EqIgM({gZL}zy7pIYOA#krZ@H9|7{Uzgi>xjF42>|T5b155bemPoiC}gL)V3}rS zX6)?jAAyXcMuFOryO8SQ8vQR1;McX5f%KTr4{qu1Bl{)5o=v+2*juzvftUUf10cfPlXG#Z*S6}SfGEWCl+WH|K&kA5t7-!&9E7oAZ4me}#d zyF~=kaLI(zGAYo`)rvK^0-^vK-&*_>$gXjO8cfWFJ?Qc-lr8#&!JxDb)V;T-OtBojCZ_# zXSk0QbImp9|NmQM?{$VonaV;)Z?Jim;%Zs3MI$*rDO!0U4~1!`iU!c4on%I8_$0|1!4&eBXT9 zWPOBB@LG-4t{?uhw9v|2KXq&>PhBMPf`a1mYK=bWLM<~RgV5h)e&1cP{CEbCNHKsS zl_0=XXIIgn-T9%;hxaEO{%uA5itD#Idbnp>*9!xg1o@4s#l;~)ss6?oQNx5JbfCt@ z#!y^w2txXDOh^@iv5c8C;1!GKP~Y@U*~6FjPkQ}pqNXPI%*SWLZV% zvq$zlkcsua4W1C+bhN#GJe>Wm&Ia^G8>-5R+r+lKYRDYA8c2^?U&!}IWl&#JyygC$c?pMTr8I26*GzgyyN<)yDlps|Mv`@|U!1l3T1 z+_kl}&C34bVvOsehGrkN2GAcPp=}hqtct zN6OFE+(*7VqTqDL5~;!qU_!ajA^{KW@>tEu?IjAu%M+YIcD{C>EXGGcdm=F0x~rlw z^;_Xav%v~iXb+X;1l#bnGc1c2m znf2hPIMSZ*v9DLRng2^SF-aFFU)e)B(U^B0(rwdw2BF|PDcGUyoybQ_(DKuyfp6bp z#!SPaLF9L;uQ7g=^|xhfYQ-N9Ol7cLs(17(?K+q_Eyx1`ifB;#uR%V%)CV@5{yB{ zTE?n=%}hf?{uBo<%%YkI8zP5~Ha`x!K`R9FT;@52*qW;;DyhAC6<4c4M(*=wjp(IH z&?VjH3hx)xT4vA2sq8Ja;#R;Y_z}pkYgue+B}H{kHu<;x1g9fMP(BI1hZl6&B+$e7 zeLK_VY2n5BMyWUY>c=p;;WA`Urncm_D2767l8ht2(-dg_o1t(k6Y7du4J~b*+_qC5 zuojZ;#q8LMZiv3evHBbwoU4 zbtk*G&FfWCAs%LzXo*~GdCZh4QCTml=b~^l9!cQSiYAY`duKy$m?^B)@9GJN145|k zP_E9h)wRlGfQN;5Y<6<_IUjo}TFXk?w^>&O)|Wq;DrXOU_{jB}J;uz0)_G?Wqh_u1 zbiN`h{^(@4!$}DN5;oCZ#*jK=nPl@RzDT&eXDDGjdR2U`-ZkljvpW@|2A@^&tXoVE z&vM`nue%?sMM83Nt~!F;faulrR05$QtqyB$33JcwBYtnAY9AT(=-L6^dYp=ylUK6R zrO37OOrG;<;LmT!xt{1bGO{+*7qdu#Drc>qkkRV69$`B;zq?C^}XVMKAIhRmp*9i2RGn`Mp>#Q``5s zTH29AQO=^Q$x?O(fi4D-sGGuq9{rddjmx1yK4;vh4^k&sX8qWtK}lHg$B1`kUk5u@ z@~Y3pWz?UxB7&cK4i)a~P**zyR;q+KpU-V>r&MnkeY2%IAd_q;K-(lDN&wYBJ{2Gj z1%ljH_NpNwz_aH)G+G9lue6d(sZ7qK_T19wI~4?)M^E1Y)O6SbJq$awiN`7qlogg;tp-^k$&P7xq+d zkUhx5T?()#z?QnpM|oxSXhQ<)Zc+O;N8oF^S5N$O`Iz4u=Z5m*2~A1!0M11oHNzOD zDi1uPk}kxu`Z~5maRjc*$B(+3S9HX2vzSWEaZZ)D?>#|LFM+!&_!3-wbSc*gT_H)5Uw-Vc$z58>>tB5`1AR3rGahOCdQ-B9)S=9gLayHPr6!}UpR{E-#>W>`vF!g=PD33rlZS+@8$ zEFfsMKj{)l2FJ|thl$)EQditG`#))Ir8zG1wU7?P?~Cj>820A-JB>VyFQovT2{%da zswMr%x0iw2J*pG$&(xRY#_;2#^yI914p~Hjo4Yk>mIps}nw*Vg{c3I8Mc}@s=S2s` zW{X_z8%|hhN2Ov@v2}Yef(lv}XCxd#bHNciT2*g%2-3apV+GfHu9y>LK`D|O4ro^AdjwrOdg=~@B7))4 zsZ$E-VA6LhVqrV$X7!MW?8#e@Sd@#B$!Vy`j#tpnN+B7krwN-Wc{9mhZKDls++Q|w zoPC6EudP4^=@7-C*3N;fckP*P|5V97=xI!eL@cZ@`hcGxZ@)LeHY-|Z?HDm#=(ti{ z>~KFT5LNEe*Elnw+9?}!^&}4%z+L%?Hi`7Z*N5nX`l0?Lo&l(G!$daP25}|Uf&bYr zn5L@qE&2T@2)Xeq@bPjkR6$cbo&|E#CKoTjaQGCueS=I=W{{TE@8#0`_rx0zpHVgJ z_g2R><`p;*iqtTFQ>9rQ{Pt`*Oi>-2fgdvebDgw)1Y1qiPD<$`)`hc$Zrqn@;faVv z3IW*RZs-_?r|gw`HS#uO=15-oF*ybKSV>7waJq+@L|a5Y8H!+y7&{J|`jTiE6@<{* zqJsM-ALe=+n9iTvr?S^#*CFQ;`{?6me%EB;V&G8`IqN9oQtNFSIS^FP*P%HJXp-LU z5#vZlZ&{aw)W=-#+DWd|8dd50F1|w80!#p~H0A{uG z>hepXtNA{x0#lMOK9Ci~D>1rQ)knbrb|{7wv1)wG<6!XXGwq;ezb>1JJZ)3Kop#c! z(q6-D((^obJ_+WY=e7DKp7=ZSQ!Ud3w{KEPJ4u;OfvHn`#|v*83e zmH0avaKX8L&gTT{)qlMx+T+`^s= zbk)I0grn3;8_b*vsQA-#99`J3x#kZM7)d6WUerh>4r4v|2EnxjkE$paf+*vfPnoZ8 zSwfhOq)EK9rt=+^qvn`Gn@;2zvz{^Ms4=VQ8-@5Vx~00!jd7NJc{i0_g384gdXe)6 zT_!o!s@$P}@#liGHH1H!groc}`&oW_F0#jgL}=25ebTbj(b$3?*Z#hS=mZC*CVqrQ z1HS!dKerNW)rO5dfdMSmyAl93LwMvU1-=gSbI-z%MO{Wa`zdpC*qQ5=UCgHY0nN;xQfaRVp5o?QzTwc=craM<7=n%T4_F8E!Bv% zJnP)J4u;N}H8{NjtCYi9S&^e_2w1hlv14OPDiU&}gzjaZ5V6{{)aw-my`4J*2iib5JEbVgY0lCnqO8Qd*@_Ns!!@wl;QO z4;Nl#spH>e=?{7?;M&V`F#Ls4ks_$--1uwru~_A{&gxmM+-C9NvL^V+=UYQR>lNB* zy)+%?V{XoMcQ{*sSk$;9fpCRu?y@kr zbKpX#jAT0;8S+s;V|&$N^9oj*Egt6pLCd>|?BpZ(tGFPBodUKidFvP2wM@UGNN!TA znpd>SqD_xlO|D1>8tHMM2+b?HFJ|td`^v4S9Zq@GC|lYh`W|Eg&)2f- z$YVjVskI_Ud8c&bD-jRasnJcE@}4Jv9j;%|9j1jGR$Ng}zL+A*<_`b)GmM1#hWBSo zW(iA~%tZ!?Px6~ZE*iOn%r9A>$TlB-c4JiSuO%8d`6hUvD>hrbd!X)!RQhD4pXy{7!lZnzL!dWEayR$=z%NI6U$O_Y=lG&{onEa5+m&Bba-|KsDC~i#6{*Dq zq?UFfxk6ia-(E)QS^bc;t{6js^bkdKu)dV~fj_Db`FRA!C`QXp&PDTG?qi+y1$ zf)SNieGtxV>_reN7Ab7Ta-C`8c=_4Xj!SwFv&<3lq>vTSfY(5gtF;XSH$0LBE0|Ji zbf`@!l!5~-lwOWco}l{M>Aq{&#aC=_V4H$Di$q23@VtH%G|~|^cOSdpj7s;1gypjq zwaXXLg+f9HB)Di7Su55dd9}ou8*j?Xeb%07uck=2!s=?Xlfjxe=RUU2Af@v29;Oq2HXUn z53a8CwxzHd<8F+k3&^wGy5zRh*E9HfShB(wfnGTi*_0;#7QeLr8HRHuHvLzlV#TS+ zT35p>9x)K^Dpf_-N+;rp?2lz}X+X8*w=Z8~X=`Sji@K}c0yGVubrfiAZf8xgB?_Po zCS6^1w2`nL#(En)CdCL1F)G*&fdV@!8tSK=-!}=hknmeXRRVbkuwr1S*$JLOeVWEc zs9~6i0}?3WjF=n`6I3&nL@s+H%x2z7HP({LPA&BqugJRB=O6)n^hRNdsfY@>xGaHbn=rgJ+-|ERdG*tHVzVu$U_^I1id2qMs$NE>aH>UA2xhI&s_0<@oM0THbfDebY&W{5 z*^t)GX;bIuL!w}}Cj8Aa!*csfwQM?2{xm-GYi!cS>^&3wb7g5~CYtsh#^`FO8kzkP zIMhNUZ0se!{SwIR)5WVWnX*&SXWK}s{+(?Bhi`X7nl@i zIH6Ta{u!&<+q$RzsX7XRjc}PWsQg9Hon~!Hofv(0=ZWwvQw08nX~~hevkkxQqZUqw z{NfBT66li56d}S~iqPicE5f8_<_cRDYr&H4Br|hI%e|8t4P;L%X}?9aHfdTu+GVZB zFx*y7CF?Jq6^CINCky4y zDpRXDu*0&*?T0vW4%sXqogaUMZCjgFGr4U*1$q7COG+Zxz~DHHmTEg}j%nD*$h`YP z#Ksf2s;LGm&AY;QPk@8#r+J~ZB)<={g6$*S$w&>@Q-vwjsM3cTUYIRDa{+7`1;q-H z56;u7K16Q;J;R51DoiHN-QGW%>_HM-F$(!C>)%D@dvN+&6of=u>YXN*iu%38`dNfs zy2r%wFTSWD=<~E0Z*ZM$zQ;o%Xw0o$Ws-(yq7EnpW*tyiz zK;Z$)*%2Z(Sl7}BUuF^YbEOgRzj_!-WbMj7JSKh+`bo^@ySqvT9jH|;e~YjHoC`)f zCZky&=ZJYG+LviF~IK1!AG>YeoggoT9L)7 z2(4bcIas1TQpmhl1TOxSQ|)yC){uj{A99(XzGsE*o;gS8an*`olhT+29*;h3I@m7uh^wGged zoHKvUG&|sQY$C==V9V;oug|S1c+@Mek+dY>g*~7FqLZItI6U(~3$J+?@82G{+qu}| zV8Qyb_FBppdt`!@G+7|Nz}n}o%4$=>P3qa{_oe=T+v&Lek&PP`>ZN`u9UlRkoVN}r0FDK z3 z0<{s>?XSPJ4+?->_{R=nnMkbCFJRNE9{~g<%C;w1h)%JlyMr|ZOBq6`^5^Q%g%|0j zCWdFjW#olmQo0^F+nDjq9Y^Uk7l%^zzQ|+K?EnvoYd5ZG%O6cc7VHY3CWz?Q&ETgcP1hB$>vTk0tW6K$gJ5}p ziQ~I-siBb+4S9{^LB7oGxR!PxNIgh*XW30bU}VH;GD(H#a9VanYTGL&`Eo5-Iv?AB z{*b{gXcYOJDJP-c)Kr)SHQ$j-#eAG2`LRi2ehy>Jp&11OQG50AM$)7MwhJyPSg$3z z$2cfon+m*X7C&2{CH5x8?ju7H-RwY!RMh8(-HY@l)`11{wD1P8mR6s0<0MrD2mx|T zj}SVQ9OQkLxY05(0kNCL=l#SHIPx}4_oU+X$WZaCl4lW6AA7Q2dbe^YuL1~oORY8> z3P`6q1KZU!pS+Pb zUly~P6n~EY>G}7=5Q~@5AK>2X#rvho1w8?Xk#FC+%xcgk@4;4L;H}3tfsH)yn{+_u z>C{}fgW8XQGL^5pCZ;yi3=_@r;Ri&fgrA6ht$vilauC8x`iPUxdl}}7dIr!cl+w2>dloz`o)x$8Xdc^09Nn)CAK$C$j3YSH+*0w|{vSHl3bd14Y( zntxaoEUh?T_+Iscf6(MxDsfLk&%69bFz#-=;u}6 z*hnJ=eZ7NwWc4*Rx0sjttnRJ$KIEnNrDC5stSTXn#HzF9tlXLI5HBQZltP|Nypvgvl`vh zhrk5d$0~nxWrI53HIstYcjLGiK@f^p5DSZzD=k%2k}T2Nx`{Pdr}lAeb{68)FDNB2 zg^@}WGO0-jCo5%TS7CgQCcXbq!kYm#b1PXfx8~Rd%S2t%iQ(P_Nnh@j3a1HuiuOI<6xdOr0~knFw}rkVxEc2pbsDu@R5h|ZHEI=kG{?Dzbg%XZE{?1 zVNdC<6(x^vdfia*O(&zrJ;nDfNo$6NowZwvhp)OdlA1_WFkk&rdU~o}KJAuOntI)# z09YMaXx3Ne=FmS5GJKtAYZJx7!a{>M#8Zns@~$b0nwr!&Ym-p_Xg@tB|GNvN8FPOG(&s zPBok2kG%M@rP)@4pGC<_b*i~p$W;6iumMVD95(|NYt^@JOJOY?9n=>GO9bZ#K<*p$ zX~#ed+Yflu4Q1bRN4!->60S2vAIm#&qEYI^AwFH4 z5Qr`*Ye??3#`k!KYM(*${(TWERn2?)(&GMywTwpX(bC9!8){ktW(T{5rx~ z^k-i~e6o~j+%;O>e4(d94iOcFp=c1##GIJV*0C=fU{*s#va>gFDFykN;T8DnlM8h8 zx%b+r1s183?Nj$1agMkbW;zGr9tp)9JZ`FshQ$$J5{m@kpR0&QExptEId;nhK|_xtv}t9r z1Vw9}pXittQSy3*m%1J0S#5W;^gVP=lzR_rh|p^JE^UHnd9nY#9DP{;p%0@2+C+CK z^yUS`wY&J&EHQC94^lf4PwedkW{o~7(TxJPur7AG zlNiRK<*{h+uQ%i;6Foe8&m(mf&OkSCM;}S8Y-@g4Wx9UUK`HD zzOsuR90vWvUBe%6jLs)5eur+rdL@to0v{uesY`$eAEdPjv4!gux3=ofj{4Nb#m8@S z2crh5-M;Qc;CcWH5iQi668_CY4k)YoWBB-927oxhVZnl@RVFVaux_$EBU+2`5Tl0! zgT>D!uCqnMzL`ieA6&5_HU0%?fuOp?^l~ zP0Lm`5Tegl+i`^Q8pHA4aT5k-0Z(@g#Zeq3qa zodp@yK{2h^Y%v{)75R?=BplIB?wZI)ud1H6j|Npk84Gx^%l8;4M?4(!of9+3@J<%E zg?aB^NTNMf{m_drwEEiqPyxz&$#TeXkt=nLOfV`on@*jVGcfurjkfdVUM5=}Gx~_l zQPa6lvY!+-LxlMPKe`v_Y55+=_KplAI-Pri_~J<4mATnC%*o$*Tx<_{ZYnnmjQsxn z-!9jnw(6iUk+v+wPg(M4TkoVZVziogur8L_cz!F>Bi$cLp_IR+BLY(Wx+4cDeRBQ7I*MpgK ze5+UKxz_vdehwZsy{|%A*(H^@-l54~tY*dY{ifpL2I9wD_#8@6D`exx4_}^ZfqL+lLvqhK z{Zqc@HOux7&0<^yBl;VTukzP!w`a){R*f>z--|KTH&|@FGNoAZc2b$jWbQeqW47Q; z)X~n%Z6Npvlvr3|*7AiwhF0H(!^QRR*Fd5=TKO}3Aq}Ny53k+&Y!w&bLb&`K)+Jiy zwyF$GZW}ydc6W)jR6UJvWMa$liO;Q-^|4Fs53I()p5NmA6{r(kEaTVd0ps}U%J%I%tn^Z55W-#VtUDzSh8Z^05haHlhvc}%zxCu@0#`^au7o%|oq&;8i zEFmFKzDOBoKB{{p#bRP&JrA@Ea)6`3;ta85v6Yt21FI!tjL+_F>D|m^29<@+)n$yJ z$u>}O#XQl~HgwEtV;;G8FRWHUMp6qaW$g}sqzF0Zlq%rS*%SWnh07D-w(BU8bSa0*y8 zN^SC4n1GT)waI6banX3Mg-Y(%cQ4(G)UtF?dZi?+E%tSx3kHLs;B)-B&6CoW8fzZY z@-nid+TzsDJ}|JPH#_KXGhe`Kc#kVTKbP1~$-bN~8gN-o$M|@>CN=!rQ)?2|U)wd* zh=nj>D6|DQP`Q2dKAWEENP|x`qqNSX^x+g~9N)!~XnCpr^K1wP^ci>s!MIfcGcfo? zh^KlPaWmDEQy2{8=fWyrr41n%NCqyYuywSovbXMp8^3D~DI6 zFn+C9z)H_eF|XzgMXcj4iAt&89{nxM%h~!Y~^`O;=QF31vhF#l{@&FGd=spGpF zI!=wn)4aR_@~7}~{r#Tam0=z$BB;J2>E`9WKQ{YbLT?UCZ$>nv*HLFl4q5NzonqB{4(@`hz zj)Gof8}M8rASrF%rSeQzxF;DNwn(~N($)TpEc3-MkuR>7B>FM+T=xrEYH-Vh#KyxE z3MZ%ve%Oa4`(>B zB{BOZ#G^7|VCnYZYujL7UA9M8-OnYj8nD{AeTn~xOD$>t~f=nZY=$-PQrqq z=?Am8=$r~(;%(zXn0M5_wAm-3NIQNNnLqD~nU?@_Z!W0XdZHeY`ks@yo=-ld23)ha|Hz+# z-k8%ew-3%CQJVeeBrf(c=2=^4v0$5%V%Cjbh5*O?zpW4cPYxPjXUU=9VGZ$92{MJX zG~aB52${#h;#Ej5f{W|u1>RHO{j_IsT|}_%3C&l$G6_oxS0NwT)TRhR`35(ao@2!0@l7y z0RaIL{x|yqKQ=el?rv{rC<_Y?_ZQ2Ycm2&J7a5%h7X6TS>W3C86}0!m3%1b&|IvG` z8NPKgBP!;P<4e=QwGuDz{18bZizemOm%4x1D}SkB|Cp!$F*JY)p_}n%_&2X13Ow<| z>|srR_QTLLIIlt$rfU3QFGa=$<0qpQ-XhGu247m^i~%*>hqS{%-uQxA17SdAv@Ej` zAjExfaQ{Vih@a-Yb|RzM#X~m2^KqXgl>Dbh9{`gg(m$@afE!h`>D!MhBbnYV3WltU za5T_grtsacf}OYPFja@#{bdy5WP*UEW$fIGFl@1^ymcFG%l9UPl3bVpSnq%Qw8F~W zC;dRcBP-3b7rMdTFW3`E+SAH|?5D2XS)BC{ckX7v%)8aLli5dvIHIeeEgo;-BB8j~ zoGof>G&g}-HNDs^BY@Pev)q*ZXp1ucgyxni-fy$UpA2 zoYBC5g`c1JdNl*~6sL7D!xc-MsmXsC|9|;2iq^QJ`kye(+aRIs$(okd<~PtW4{2x{ zi$pJwGCSq$Q%B$6oVtZq(;%HMd*-xl1`0l72`ltw;xnY9?0dY0xL_3?(o4HAB+XXQ z)eRK%-7s<`7Mk_hRfCG~Jj0i?;(V8-!8QHB$#ZAlDzPcY+^b!!){<|9Q|>iR$%!s} z==gB1SJD=t3$ER5n%RJOVY_1T;0x-Yt}e1iyVPXzRcvS$nT{;9>QvU`-2+Y3+qF ztx1|M0L&WUoPZjpp|2HGRslxAPG@-UH6Rggd8n&yES^mZR5dR683OOF~Ey8~&78rFN;xrZQjkfKr&` zKVo~W0*Knc{WvS1f`X!_tt7j)W;GTU5?p-C)2^xc??ebt1f*v=iN}MfKC%rE^X*}o z=FEm(CCW4Cf5NWt)^?ayE;*!8no26rik0W~97d5&8yMZnKppDgKvosQz;FQr=IJ;2 zNUWP3)nddkCbeG!--m7>^$mROg9QxG`BoWtdizl!jfltaU73{E=U;akILhO$?VLZ? z2lR{If}L(TKYv!x1%ABKKYl!~;?!#foptEjZ)Eg&`qyFw^7@MqUm?0e&aVxi_s_k>i;dnc>i#l)pv%K5oCw=51eH!_gT&HHL zQ{Cw{q>3lAWa$?{qRG*VCR&;E%DDP-emqN7HL+!3TFFR>LZh2b$l2~Q?IQ2S*?^?$$kBR3` zL}y>m?0Q}X+-q6MNcD)|?OA9Ke0GI%o^Oh^Da75vYVYCEoLhO)+sf7ku&^%I|2|Rl zng!O@j-^9B>BmOp2Fb^{@IfwuI|u5){^HAy>^vRomVY4&ep$sJ-3QVxm6*FM8c9>6 z=K}6W;O{v72))qtBBU>o+-7?o0dQIjn_Xe@yN0MDRL)bx+H>fznCWHbS{gQze7nAC zt;1RVt_MXHd^oI#UVwOyN9Ixrq`|f4n+s-g=L2Zo&Nu*6w9++a4WTdFOT|?56UVc3 z?8Jd0M&+}#C`!tBw55Pu2_ise{IZoIx{`E(DX#1E$-G0k)LnqBTJ8QDn?zzTJ=%KD z--Ec!6UC`v0QUa7&kqEIKd_U(4+6lU9{3jr;C!!I*(F7ga>2 z1f-!!Ng=}33TO@LER}iRvUIib^(x+4`&y!x!CCM2hsqNpUQux8+R%y? zyTG}dYc%*qW>qe{k{MY8 z3Z>U?J#kCZe4n-?>i9^h1I>pha6xp)NVWG4 zr)npQs&BPi=wZdhnER^j^;?sE3Xk4z;mg{Z8j`{*D}CU)5H+~gcN3hS z+7Jz8eK9+(5c6b${Phjyp^Shj8I8E2gXi?9V*d+eP3GeJlWiEk!|9{{j%VVnT1)<+ zi-#YiGzcRRPVGoa)Rl6YeP)+Ll~DLYjDwjFzPmt8&cyiEfq=Stk&t>Q?JXxNg3!n| zU*bZ-?v8lHA{owah0SmxHKw>Rq9rh7rg=oZeTLkG`l+01i77rs9%d%V-!&N#mfD@% zyL5uRzwt$+1W#5U)qmz7<&Sy(VyH8&u+R-Q5;4pDmNe|`Q+{Q95)tuF0>3vF-~YB+ zLCcd*$yQdYW<==R#YH(DX&Q$g?Rdx0@-&JdKH+_!6cMgM5Uu>AEN0o`LYv&(lGyp& z61#7AC-pL1>7}Ht(V@i7T-pzrDoDsFJlafQ@eVS&VN?c2gzwLEpNlAgscF&~+D7z)n@!FNzOEAhEOO-xuK0{jMF}gFDdkDWq3TY}!pGFs5&(4w6#Q@H7iQ!T$M-kRG)EwT4BzrT$8fBUj2peGzJqzabG zc(Ce#!CXm$n@NJa>(T7V*!FS`QLm+Jp%Qi2aRXps8rhn%-h{gVytR;9(o*kl&xG%~ zM>nz&GNZEY-tG zQpWCT{+t*cx0oRpx?cT!Dv!@gMohQak9h4NxoMk6G?6ZX&1#@d zH7@y}%iwT?v_Z)bH;z(EC|Csx;nB0}*%!KwA z#gTv&d6_H*7@)Lbp|rAyV*&WnX0;^O<0g+^l^pp=;*3tUDYosEzHRh4Vz6TMQec3= z72AX`2uGrEH&V9JxkGvIFj30_O_K~RZ&t%52_&=B^0l_|8M-A=1fj#CQENY7H)~G1 z&j<{aAC?NotZDvwuj;dc>DP`iA3o5#tU5K2aA{Nt=E>tQndN*^s+a69+@!!0QXn8s z_HF*TyZ>Rx{VVBlF7-x7!)$-)qVjcKOGR-UB1?K67l0wAF5w_!z zACBlj)8iHvj6Lg9`qlbwvik2cNrwp(npNATV*~xfd!qCLlv}(lfWQT7wnF?(|2!EI z=X0CYUzh+^pDhmO8HM8gZrdt7_^-_Aa;Jdxy%b^PmHJD40xqtnoCIH#IknAx|Hq>L z7483ref-}m?f?6^Pv38J6lRriXVEXVSI(t%P@~;1w$^_#?LF=CK{G{0)N47tI3hs3ovFNkVoLJpHJTRGr#6(WU&J9HhIV9iFs^TV_jOLZn}0uJi`1-vkFZ z6m~lNA-MiGM-Nc7kh|@|29{8nlV8xXuml#=J~S`Wk9e{i5U`F`u9B-Xi8Ku77DiD< z+v~gyhIfghD_i0w`_}XkyZ^X*lvd_8`?Bqhc^%bJMXWz~0wt!EU_l%yT*Uqx=?!;d z(kv`Aa^IV0`G^qd#AVBW8R;WOq9^n*x=L=o4Rx+ArF|xHgQicUfK1ODu~%W=W@BH! zGeF15eL0VAyl(Nq^DFS`y7u>E1-kc%QcoO0yY~>tk2r83i+Dz^*rpqqG^wP?-oo5J zmsQ(FZQGFCtWt$R_z;otZmi_NO6AaUU8k}q$+T`SS zX=|Mf?)@iF`(MafT9A1br`9xiJn~1Im(j)73Z4&)1jXo_MA)Fq$(ZTg=J-RAC<1HM zb0+#OT_jN^1LBzNpGj=)>};>y@x@+;huu0>9{KITY~}HsM)NdR;-@mDL;Uu_=ii`( zAK_&@6X*#?ojs~FU)p>$VR#YtNQ?=0)nmTex~_L^@g1ZyI9Rju3|CKlLlJ#w3Np_B zT2`=z>b+gl9(%w7xj~26ny;D9!mP=Hw$A?SB9Wc0@5;cjfrXb~H5uN;!iil^U3Y+5 zWp7PKAnk%1L>y^k5~a-mo8B9YWiTcK)S+7ZBH_5z4Qp=(`t`2$buFRwL%V^65Jvs3 zU0FxObN0!~=*&a)Qdyi{SZii=-L<}kZMDhK|Js1FIj1lQ6`HmwX&O2GvAtgBLn5(u0#k zdfd^x^xA87yC&w$XQF2|(v}_uL>Mj-$gEmg=<4g6&&&@VpeD=v()ednjJh!y?79nH zHN5eW^H?euUz*kR=vq6bBNR%~hU58^XPkqMyf59oBzs_jOMBkcHr@Wxf=l<4AFl`u z9gvYs&-zo8`IVG^&rSsMaLLUlSsn0DDbyjwqwk-Mq!NLdg1VlFa3!aV4DN6`Dd)GQ zo87rHiOfVe#$I083eR5E+&C`nTU<2J*w^8UwLgZzd@>CwP&;Sl+#KyPTaxifu6L|+ z(~a&|-I12*toiHfhjWn8`^8W#WDm+PJKd2LLEiXPzG8t`1Yoi)5 zO^4icN8Y=k>~km1P5ugV?hn63Yek5quckb$-RN(DdDZj|A4(?cFnHF+&>b-lz#w}# zY?uojBq8xj#+=2$em`gZ8dF+UX3+mH`wNiy(k;bbI9Q%E7ql z22GT<=H;d2?PV;-Y(M+Hy713ud8~(4Vp}hvY1?6L9ePLh>xq${Y0lytno6!b0EOdl z)swr5(gax?@t@uzadYX7RcYtiSR=g`dumP7(9^v8rCI~SOP&VhbiYLNw1--_ufy%0 zvg*{<-h?E`7`yO*sIAynewIJvTA1qP@Z^@-MOVvkBelsm42y#uF-ig%U!D&ZSiV=@ z%QaRxy&5VPin5R8PJjPf4ct}CZ_K0pU8O_F=5X8;tJ>sjU`O};(+;c9>87ZWP4VwZ z$@y-JVIgITba6R0)Q}|W)XT!?wm`+)-l&z>Pbx%g1DG|`^(f_6i=Kl!-rshJf9P6$ ze$cWJ`KPcYj z`Bn;9+*R>}Zhysug}SSpQ~t)e_P9rv$|khFp4#xKQB%v1I{V@C;z}gNLX6w0rP)uD zQp+OoYL4ic*cDqlmfN*1TV#eJdhgd3sJ?X2qN=Id$^r z_FAQ0pp0kJ)NW7r`Y)a}g;`ijof+L~I?0)W5N3|C*JZ2kWMLhg={+NbbEAXia-+U5s;R%0JY zmt0Y)j#ZCAZZm9S5gCmQB`p5!;;FH>Gj(M?(B?8Uaq8Ijm-v>d)2`&(podnPOrRgy zU}yr0BB40^wj}ZT_O6QN@hv{G!pMADik`NPQn&@0p;mjrH>Z&vBUTpirYv%#nCSEf z;dUkQFn4OW2wRcOXD3s#j;> z(!sq%P?ePh>*LazRLsexo*~g-^ZL6_r~bDj^S}9I{2%Rfbs#oYDt(P~*@A&B-6%hU zt>}&iYonJcll+Q-TCK)?Ce=Tm1%AKFriocG`sY&Gnw7KFb=VTefx=<2{loNT@!)j3 zi_kM|%PaNmnZxG97pUG3tAn6um2Zy~s(H4}!`DoE^e4_6|B5i~PL!x=LyarbQPN&I zxzk5cZ5GUDLw-)h4`yb%|BZ%3{FvYie0lE|+U-YAZ#a+pTRsUIZsrWTSH|wB|&wU2w+8&e;65LY#zT&w20K>#5`51ye-#aC7x5y8^mCE*5l$ zNZwk}<C!=LncalmAGSBn5WjizmP6_GARC`bA?GNZoo?GDdk*#;8jI-o3%)f z3`Zx^+clrLo(kz{kltB@fdvXDM`8MBFCHsnjn*&A8@&;=~y4i zJoEc0Md#*^4<&5Yb+XfF2CaO};qlf_-Vz1i!s)35<>h+dY6Vv z=+GphRO3s@#Yod2mD>#k8gvQRTZ9&k9@3r1RzlUWnuxraVYf4RuwDj*LnkV(+G@u~ z0)KV_$y8QBO_6@VX{}*+L0sxMYW*^G>7y;lj#bZ`N%p;=kwskXLa0NOk zc<6b}8h_P(zSht6dvzO6nk|dy-*+)7gr=3B=Eh3*A|!{yXnVw>tUvQ{P(_Qo{Vvgs z>>3CA-<&r?Id*|cLIFZ1w*eiO~flfop-iLT^Tb@NutwD~42r!1x^V+XTH8w>~ za%lYqwEuzZ};5z z@sU*ZW)6pWW^k>2cHG64UD@D#E{(hWlr|4FWLiK-ni`k((Co*COmT6 z^mz{iCtjPU?p#gHy0f*NQD+T{$2K%IZ-io)e@LJ`=?%Q>PYILSM+qelSdgqxlNTbwZ|F_%1Rl^bEx5r@eE# zKN|FBTj20wiTk?P6M{?dge-mkC%R2$-kS45(X(gHZT;aZ*3LC--In;5KIxa5_=CM7 z)#nW?F>m$)JUTzwLK$Jl(+s87mOt5Hp1fp`6f#%*z%a}}dwMm}EaSd&>vRFfLx#1H z_A3p;q(C;bp3vWv*H@c{M#dMDKElCop`y@BEyap`@5tp=Cd_fgHBL-HGYZm1hjOb{ z1qN3#56>OC6TjpQ-5L#ym)L&sqA#&e=negu@R9gtBu5+&#KP*eq9!%n)E9k2OhLh9 z0u)a05huZEsp}61VWz3D*a}SWIN^b@Y}vajssaZd2>Z3PcPi7GX$5pmA(8IFe_qZH zT@SQ62XDHq_yp>eA#^Jn@U3FPV??bcA>Ry1Dnp@jTpPzJ8!Y+}!ljZ7Rs|YC{@v#f z<#BdtTYs50(o2hJTrXIJlVI4^_BLWcYCThwh&mu1pjGnonMH zJ){#3vDW9}4AQDOiR$;K)d>Z<@r^vwh?YmepcEysj5HH9akm2(!~;rBd9e-hqn4OO zcZvk3khKpEnZT{O+mN+4ep4dDV(^N^&;N1%(*){n&WpZU7ODMUp3xfGGww*kS@LE8 zLVWpv6#j+-ai0)C`$MEfiPawYXmacVUDan_Am{?Yz!GS@t0K+ybBRm&xfjQQG7U@y zmXVKB?S``sS3LUq1(-1ht|H8K#g8B%2CkQ5=Wa@Mtc!X`2uJ4iZu{NqW!HJNi=qid z22D-ul+JgEe7E&AAT0a@9GSHeuF}81ANsO*{(<~~3wIKaqH!^8|W2Xch;h5o1}}h zz>V+UYshRLm%oCZ*o_WL=Xi)LB$>Co2nGf5i6&1M<%Jpm+A)CgH6=&&wBJ1D>{h@0 zytyw-oy&;~I%O|f7;9)J3wprSC0NUL(oddom+$MJT8RLmf8%#(i*xW#9BkN9P4y5@ z^;D2>yNkF~LFo8gu{BP<=u^*uwiJ@NVI1894xVS|jF;P7_GOKW%baBx{YT}4=i@Mt zw}4_b+M`0Txxw(!aC=`HpYb^b_lPfGwvURQwpBgDlC+j@3?z3F*3ay#!yZnk3`GDz zkDcD&1dXgCT*FtIqz5l{#7`i&Kuj*6j7cR6C=?u%DxH=6hr^d`@>aXa2IUs1YrFu=)5{Dit! z61LHH(_{03TJnM;tU-JiL^F;l+G{Kby=&qJ3k3zzgarxc*Opz;bY=tFvla6u$`b^I z!j6gO!L->63AbjqN~&&?R9|v;D7CV}q4FJ_5m=)2Wp+QoVNTvQdO)08_bF*&D;oeb zYg{WK&d*|i308Eh@0|eodtG)*AXQaW6?0z&Rsvp@2b#thYKSVRWg-mvVId^r4F9n} z>IT0ehDX=xkF@lR+sw5m%kE?&g9ta+q{QS+3$$YE@bEdvZ}+$CDTY_7%x~=3db34M z@A~1$G10)3+&AFtR1Wh02ipEMSfs3~{ivNZ&^P(i`2K>Ta7@z+G-s#W!m3a(#G1u2 z`ObS{1{x9@mswMDl{54D9>??(XzYlx6jhh!pYs>CJN9%M`> z9PvQH9@Ji#;bMhQdpevN92WzVV~PvRgIcH~0_ zHdlrk{M}%koRxh!QJc0Bo0wwF)^>LEq4T532ST0L4_?ycu`YxAx5bLe)5yGEZ~cru zVUrIM8D?tp{?#{>zUg))tDq3>V`qx1JjWSSLXpT1gexxPy?Y+DT>ES4jRB*#4V$22 z+M{utI@Ov9cIJ$eZSd0G>bz1x;r#NApU3=VL%;7l5Yo)X(zu7X)Ql2Pd3k>4+1rI} z9o7B)d11N=e|`x{L7VTx608CYu2zcIrN+eVep``v>6}B)fY}62{qZ!(k zh$h3sOdk@Sa#&4rB(`&Blxdtt`O;)jk6#~j*x!eSD1}!-z|!fcc#QH(E>>d1m$S}T z_d#%0&C;1NfAXhG?sRB^R;a#-$=m5opY7+SH(n-i?Zu`WLm#&l>Nq$n z?QA?=H{sXZjn?^69$Yu157jp1it*|j_|UQ=F)U(TkQ!9{yQ|&7?=#5ZLEAmUfu*?# zxXy%9*3YI!E!J8q*>L=q;%#jkVh@PrV{^XYNUHC3Q@1PCYk!v$m0LfJgy3i6^5Tkp zD-A<|AklSj+ufR@Gg&}UQ4L%TJM*N!79x~G)-J=qL84xCSmRDj5Er_G7cC;RG(6wg zLfB_+Q7}csJ-y>gemB=j6kj=G`gYpuKJAAn`oQQiSx$yJ_0eZ6Bv$T|`cMC$tqSg| zi^+Vup<=On-=r$?4$do-CoC>T?7ac{dJ5Oh$&_e;22(2A_s7?phRNYPN%x_M@rMJt z7teg)HC4T@v?1Ahdp9of5d+uNn@pDPH*@##KOY&v@;mRYPb^}s#Sfm6hL+*T5fszznE=uM^_BZS zl$if8Z)3}%RQ{}xFf`@T`|-5?593AqsT0Pu`Af+{$5jm~gd!C))AR zKUe-M0pvgYaLmsbR8*Dh-+X@l4{@LSV`E%y-Yxwf?kLU|@TYs}t1w(d_>m^hHqXLe z$K7y17WA7^U3QkA8lQ2ucd_<uA)sK19jj1dTFaQ3FzwP01Qrv2(Zw5tCqCO=m>>347VaQ4oEr2$_*pFB_%r_jz4C9TYurX`5@I<7d~seFr1gC78lZ zW0NiJ6f}iMv>6hpg;2#lTX!ALXHlk7FIjWyWl$uojfZbG8`_BgW&ByS9(GLo1uOsC zlk49oLjN%v68#8?ShJ>*=<`U<_L#ws2_zA#tyF6|L?XJpmZm9e>^;}ZR=Kd$9a|}t ze(MRQ+Z<{ytj={0Aj=%(C5VkN8m!tmY^-I@`sLRfFsy-gSb98wwkNIFFZDEXTtMTa z7JAW-@P>~iU;R*4cw^^&<5*tlfC`Vb;OtDBpL^14 z#d>#0guIgzz+Mt%mA^DxNqo{@|9XrUJrvs8YrH&`*n>2gKNgjk9Qte<1FCvw`rVu7 zu5S1eYQZZ zcnkH0mE7>uj7dufB(X@=^c#JDGQaHa;HcUC>+Yz`^*Ge^V-QThnQquQbAck+*wa}U zyh9t5BODL5A308MeebS$zuq?|EyeCq^$sH5Lc#eG;|uPk$4RdV)W+$E7o*5W&bW(2 zeAM~}!+U@0Ze^w{`@y_mEQab<^%p;H?3hWU z&+g`dKus6?YB=hidF+(>EWF%zs1~9=dq=47+vCAEz8hoQ8ljEMLckn?=F&neqy=gYh(;}mqii;QGL0mudU1hclI8uV- zE>G(B-ht&Ft`}q{U_>?k-1gZykT8da@aSFsoWRqu(Y)H|@|@iw9S{9DPt$(6WKF3% zoJ-@9P{-7D=2qXHt_h_5Qi?#9`7P9_uk9DE1cAZN(5{QreF>Ek@+5 zkI7ilYf-%nZTycXFW95Vwu&np&44?LRW27w@0tnqd$ClGIwFuRY?W`jexd1oXGFv2 zTQuN@+dk9lglp;L8WBUOcg!`ww-L-Ac84jM4@C|H2=CD@$T%cugiQzZh~2 zOpS4Um<^yOuc`LSTzB>0&Sbc$_=Vwxfd9GCM>OzjrCy}mz~96W36haVJ^F=;)8k`q zzMf9khFYn>uJZYKbk_aYraKlgT0P=3fs-~GzEB1q9Z{#c#h@Cu%c=Gp6E~P3ndlGb z<09Sb8J>G!4oR_|^}fc!rH7O)?F_TmKi23u#g3R*o1y>#*7%AaD-2EGg7-d+A+Yv0lv zsruCTI0ugB1yW{jC%cHjfY(`6aAT4&a=`=<-|CTP zytrYTl2WP~Hm#`@FYWi*gihaR|2FTAv#f@PJ-dZkkK>0YE^plh&Q&*STzfiSd(o@mL^ z-^N$&4Duc4VQJmzX}d2}{{Hwd$9AnfNi!_*Y#s(bfO<*HXxJx>X9CjU_?0`WJ?ZNP zlFyU;zsK73l5(1`XPC<>ZMZvnPue!aC!Udn1R&!rze;oMms8$3IZ}(I~N6zP{7Yb^sJ!kk`DHLDH4F zf2nA0wBZ%uI!(?Ht9_nkT!hfbeHaRApP-#`yNL#Y;)C zy&)ECJ9Q;!Dy2W&!co0vJWSv!Z~2a&xE`AXvZUCf`|j0wHI@PVnP{n@mEeYE8qKLN zoB|)It)z`}I7hJyeEktEPR+Whq+6(By>3>W;gqKJHN&l-vg}_8;SuF!Ofkevuiei|9wR|yMXigls+0d zQfy_P2Fsv~Xm{xCJoz6$YQ@@_Bf*SWvHqP0-(q%FMGzJ5s4DTc0$*^BA-rJ zyE0{t%h&kK+}?3R#b&x_ajbEp#WF2(&wILW^zavKNwN;81lHu8L;Bu+2jwM?1~pH( z7FzsLU@ofO;pjVHD~`LDPw-N_HlM|X;%mO2|7sQwe8?*L2gtrXep4#5)cxWP$t`aH zV;}e1icD_IGYny?=4|reWcK6fC?~!g=DLVwR(#+Pl)}x9ZalMYn4)#N<90Kt>NXG~ zdtK4BCws85k^Z)shBk)9X-Xs~&LxU4^iTTDAvBw*ESEMCy z)<+tO4i6jH{@&z&J5_Q?I6_b&;@jO{RXIiSqamAyY>BD6GgKgs0@8x~d;)@yWu690Pn@!}fmwYgWiboBpdhDCk&@FCTEGWr$0 zU}vLr`IoKJFt5AW9T347!*7E#(OH#5D<(f`%$qLq=xLVGWSRlgF$vHjOh8sQwSMyT;G(_amsmX7^VkIdf{(ziJy45VapfN8jrX`;c*$2E_>G0%y8#gyOs zS^@;!QQzmG$TP!r5yZ?@0-AEPXe1xyr`&b29;k&}TYRjS?}GZw-zFG<*Jav~x6^k~ z;q0eQJC>|n#M&a-%;?H)BtttRCzm|jV&Iqfi8r;x+{;n*Wltk?M+8=ah6X(G`XV!t zB=3BK+FQP9`JEx4Sw9SHmZ4mqNLmgBg}sT{YBDYL_ij`2gxhTvQhw~kgB(HBVbdS+ z8twit>UKG{6jh}!owpwAjh7m9c#YK?0^s0dDTC^j)elT#Uf6?Vl|_Z>+Rh!h<4)tY zrFhtZabnBeq`69pah$i(Y|4>A#EfHTCv54k@o_1&!lOqtBJ1SzW@$p4E7-&2+dqdRNR^Z;>S(U~hZS!ohs=d3 zJ|W&Kmu{*%zS<}Z6&uJqv>;NdqbyTza2h|eh)7j4CM5_%gA>~Zl;wd@1|5*!x4bq_ z&kjck&>+OR4!C3sCcm+;4Df_k&UXu~byOTs%1qZHBx2$*3KiJLwMO8&&OA6PE8iEKzTupu$_X+i4&f5CqH&1Jjl z$z`?9N#voQ?)60rv)WL-6H^t&gw~rNSZ{)$$S_;yfpkKv?6PlN*34%^QuTf4mEYg= zfeYtei+^^WKyhf1@L#o3IyNdQlJ(Pc0?)D zIkwmfam3V1>#_LUvMwvl=+(-rw6WT&SE;V{lqpGGMRP zFi8u8gLRQ(E|il_Th!qEQeOi$bzm0A%O@2CM3zh24Gh|AlSCLGu)L;N#d3&}QOx}` zC!9~U1}AUGra*HnU}IDrD*PF@L1xe)zZa0s4sC>YelR8_dcvu{Egra}wxU18CA=*|gs)#jIxBC1ede zYm6S8=nunw96%Um<&3B$RIpFz2cR+%TWxPTb>s ztpzlnrHbyYcRz>Ts2y<%b`YRLwT`y+ddKr^(OT~L;OZy~AT}TKN=<~JLh7%!vhfrc z?{twm919#vf}HaER!#;gK$>NC~K191>)1&;Qe$o^;VjORzZXIcRu!Q>k z0NRS$@c1})E6hi<2RGgBNlX_0V(U8hfZzl9@eAOZ01T<)m#Qp{Gk{b!=b*cAP8{S1 z>G6IJ8M5vk(Q@I22o<*YWF@{sNW(L%E3eGXV3ggxYE*yD&m2=TnS^h!I?(FMTlYWE z`22e)z>J8;TveNcdh%FOBVnBnjivOX2%F^(7G06eV^F@3zWQkRh}}G@`Y)EE!JHc7t&qVsE-Y*~ zA3D-H)B?fq3^{R|0T%s>jaGJ(McI^EvKF=LIj%AXHhxQcj;fpitksiuQ-Gx^V+2-P zClEez)qw)5+jJEXgjg*!JR#lqXj5-QOs<;ZJ8A$^5|RgRS8Yl1EoYZ3E$lqZu_Mga5icFn&s;kp5Em;V1x{*4F& z5<*nJHwFool3IXi68z>|RE-comESXU^=u?p`BHIygGWUn6GH#-vxoz`p_EZE>R^6W z`qSpPe3WZP7fas@yIc*wolFYMJWL5JSmX7~#u({QnrT+bex8AdF#0|F5K%dSJ#>Zw z0rnGPV%L|tQZjzB#pf#lj-19l!uKAI;zAprFpY2rX`K{xw>_;E6lKD#H}ZiaRzx0g zItBtbWVEZhCfOUiq<&U-3Cuco0EB$is2z#V75RVXA5uk>VHoxNWcQW3LLf?YW^jLq zj0Gth8&+jLE?RF&TJL{ALJ0P! z6iS0V6$hS7$0grRa1h_^O&UJgIcST9=W9WtPfJB7K}MTuZFYCVGS7BE!}h(ZyX}ln zGamz5TP1=tqmX^-ZbHT(g>y%a8#SaAEa>uFKCX#<$C~Q-DxmuQoNxNv;S4!^)xIuY zqglOKP!tCl?K#0S_1U*WnV4DfvkG)+wC8>_Gm|_C+L?8=-6WTV5SKWXg(p_Uf=NEa zKV{oO6g)w^Ld@{%$mggz{+*@!Rq{S%e+phSYWap}!Bcz?#Sz|A&+)HYqxMO+kcCxF zgKJnpGl7%~E_Tjvd<+YUhoBGToFPBOWB^QIZ7Q#uYHUNH7L(XP3W%sndmG`@A9LU^ z-!V0ua_Uc`hr%X# z>$jGmElxyTCUgSsPy|=ES5gR#l_j)>n(cT?-*p5z69%*2(^r{{U=wtzlXcGKl!m92 zpqwi9PGwt-kG80a)zA@sT0ut;xFW*g#DWO7>yX!^0Xg9f4Xo;}wz;<3S$?QC138Ks zJ+}HP3YBvBnQ96G^^w{}6SWVmO6JSKV}safn-dTnhO$WMooQCmmLI$itqn7b`6B$=AP(@apY+~(cA4ixjZkr`v{%2|eQ4yE zLCvLr6`4)3s$)yD)%G#hBQQ55f5Kn0t`|)j*yYn+3ashCWOaHEsJGF_?HaENU}C;C zd1%(e`m%WarJtPtr#(Pf`w^Z*)HPjLeLFwmbl9X49S^hBAi>-WWSo|c=>4I`<~XtzZ8_V zEzouDTN)LULBxGmNceC7nWRh{rezA{zMc>e+qh z`E%#SINJ@u>=UZ>i!ujd#YdjlH@~(6Wjl`TUUE)OW9n`Zcwcd9LD#SlzI)nFa97Wr z`?KnmiUSQT*TRT;!uR)QPF&nn#}q2`Vq#c zyP}-;ABgKzjbL3ewE0Ss9C6~BoQgD+d{-e6X-Ya{lXUxxkvyi}uO3bwg}t#O>aFYs zY%qM+}^`-FOM;tOzwcrcnlXfJ?$Td zwkd1{zNu5l#typW`k6blks_I51b?d##?snJa#jJ1ig{D9LTyUcvEIecvn%&O;+Zq- zrBz0$`N?Z~lvXUi4sBz1XzpHDP7uX^AnoKRkm6hIky!<2`sjTyH6U}aW1iijYWU|j z27#~1?@Uo2$BPc?+3w3#&Vnv4V`jKbK}J!gr|!A+L!P;!loLa>jfGH``4rf*eLjS2 zQvP&~KVGflm`($du$!ryCYO8EcN0;#s(19#M@un%0=ST(jDg#^hmquJ`A_XLyH55Q z52o5wX}N}$%>66d0+jJlld}tbod)weJeKtUeRtxDk74EPI6Q>R{fxWkW0ZHB!eJD0 zmEZrdvW=%dH0IR#ndEUh&~4^he%)ZQDzSbOx7;oO)D^8BwRzbiRYfe7db0zzadpah zEAebHMF9EKYEEIwNOd;oNvOl$wi3F-MqRnO{v~76jq;aYi>f-Em);x$54VPf=$H~M zjgD2$YRuhIivPEA5oer_6{#jeHzvFSIQ}M@|%!iFtkX zd#Dxdv_w(7&Smp&Le}$h3&0+9iCZ(gzgjyJDVIeC#<%?%+d5xib$8FwF<2FUG~ zCI%%>mg@~84DG1uv#AQX{c?5?bgOGDQ;+_k&8)?J1Gke%dEX3!Qd@2=F%|su)K5kw ze8i-&wRJVynmM@L8=L5Exg<6@hs(h{VN4VvDOD7#w#dgY9ThYl^~+;2U`iDP+?`#4 zl=`vs2i18*P2~6FTuGJWzDQbBh+Bgr_CFtZ(ZIQL=T<+f;y@sw{>3mQ-H;0Dtw)~n z)u{Sn!~K}rH>=0bBD(&L_fyI(5i+h0eF?>S%^w+jIKq+Hi<&6~tQGD^o1;{uqXM{p z5?fMbfghE2oh^J*-$iPGs~PRKLA-r6B+SsnxCiy#Po@@1;ZSz>Ok`oP9S}5N0ZZR> zNt3jx+)wr|*mZQS(;F%zI{M@xz#>ZU(0D4htHI2AqGTE`SD%S%ZdFj{p{zR!uVg7V zlp60`gEjNEgUC4BB|>M2bPNZWDnvBlz+u#D1zELGvkC0P0w+O=#{;r6(e=fo^N0uc z`+t?_dAd~CJN*bZcNoA$@qvhZ#$E;@ECH~?C^@1GB;WlN=>cOdvirgAs!_A_0d!sU ztA_biiGZ(q#*Vym%I~X=Q!JZy)HF)@IdhLd@n!6NPNkdPM6`=zjlIQqVEICLUamcK z%ji7xIMXsRWmW?WTQpwk6k&i8j!Gb40-=jwM^dt8VKX#a{gz{lCc@?Ot1OdoRT*H^Hr?L$5#uuO#5#{uubg2N(H z+gFI8x_FX(!}DQ=rHQn8a7k6>?*kj9WqO=gfWfhCg2Wa_$Dr_H?~~_}wh7Lj&bK)G zdhj|*3<<3^+E7bKl((KoX;UgY$B@%F)@8h`dEF=mQ~Bk-n5U=IYh;&G=9dGZI4OCn z)Y=Fg6oOH3Z<(isxX5kfyQI`Ps*W!cl39yAvbFx$8iuO#UyBpJ7@P=kmWB_HDVIy< zP4_n^UU5aH7e6%~%}pL^-6omGgkK~oSQ65%t|i%tWo;B{fG0}{`|~f2n&s`fArYdu z+>9sVTS8~;Mpiy%tLse=eSKeKMQkUZ`{8FnFzPcdvrfa4Za(?Y($}OQ8Jm&052Et| zWdoiD{|O$Pd+m9K?R^a5hW6A~%=(U*;K@HsKdu}ub}BRdl}19V;YmsQmh+s%0j8xx z$(Y2kPxh4?0>@*H-6G+RHpoYv3_3_>d;O(!F*jdYlz@t5t#*=+{u@KN$~Xwz5UU+` z73yJao^ghDnAW*IjTnM=V4Q($tOm{2`T5L~ufOl6;F5b2>-C^9DR9P491(b`o*h$# za((Jw%GEu2(8@Fp?;UuZMqV3(tu%9B0&K`mGf*OvIfUT8IrVLI%)W17Pl;(3F%~5t`Zlhtneb~)HO9jJ%L?=Ej8RcZct~}Fpx}^%V zc>zA+b+Yi%kq4EA=y^qc7M*AU`8_fq*3?Rr=g{}<4fQF+BNt3@@~3Ag#c9*~mSrQZ zN!a{HKArB?GIPcJs(0IzZWD6PN|YYtAhHxtwA!?*mmh5m4dMmKf;0OFM@ZQj`y*MuF_bs^9e6 z8;md?)OR)cv0f-mXAC`U^&S^SoSjd)u@bK-;g8f^iBzTRH6?3Ab$Y%MPmiTA;3EiU zdjZ4z()sDBycW?8oUc6aagLAVuSA#w-g2pgP)6E2KWVDM6TPzzJx2%3&C*?UhwQtA zWn_H}yivOO$Ilf(1C2k^S3S$~HhdDgQbZ-Xe*|$&;Gkv!*a1tVIKjbJ?qr~5aC1On z)>v-_Odau;(($T!YUg+~*Z9rH1(xUQ@+@U&X+WWL*{M3Ak0Yil-q_#I$Xbb^iZoD| zWV{uVWSOPShdzA(Go`X0xLA2z{r`hFcV)lLc~c=S(~&-LLuc_ZCW3M)?VeU|gay;z ziJp$>x1wp)d0n`-(kxXFbNx)*D;#{d!p62N8(E(Sf}`rGIY{}|zYt=zB%mCXTSrO{ zqR>NS;tPb+4y1@h*~6u~%V*iZ2~njw;|22u^NFB%?P#F?~ z#*{iKo2hbow7##onAuJN#EeXxD{P0}Z+bE>KxV^@fO6*BK&vT^k4OSLyz&S8F9HbhJ&3={qH!rT~A9BQ4rX*+aj6t(b5HZQQ^6`9VY8*f_BnlJ< zsC5oGg5#HGU%Fd^EJKiXm`B;P5n2j_!5ftI{5?i`WTz#heP12yuR^G*$%P}xhW#T< zN~XnTKRR~p5lzRBm3~njf0^zS9?|gNKa1j)^WScf&UJm?u_3}P4j2=$Clfz2uMBik z-T)A#*`efOc~!Fm4HuBTr9{AVP=mKYO-nO*a1H?9aQ_7=Ks1vS^PA z6I4pcJHXQOP-Dd$8y`SrAOUaGwQs~35`_xhs$lUEocM5;yyM77R4o|$>!nG)kOG|3 z2cX>A0wpjkeHDS)HBw6L$X)yvvW_YF$U@1(wr!yBsA#pucIInd%hmY-IWD8uJXm7P zC+4a+=;mpsqpcA2eHhZMOoxw_iQ-$5)430uogH*gHU;M7C%qGI4mr7pZ03`}a@9b? z%QVpx5tJ6`M>&W{6_D=HvVIpzcQY<+CzcZ2NC%eMzLyp^pFHGFeZK`qbwP;P$Z-a$ zj(`?v@hm)b5}cQ!0V=W%qZdIWQnvVZQ~s1`PBRSnWJbz~O0UwrZK_1haTF|qC z!Lv035`kyT%gNKyS@HBJJ>yd-sZ#LOK;lWl&&UgSPoZ6ph}445c?U0x6MYUyLv9F_ zx!Vrn{|xp;7_}`uJKOQ3Ci1HirT61<2b|(i)vBEMq3!;Pd8+t*+7>gYsUdD|2S$pH z22Q51*pRxOPeR`nbCy2RBH7ttCPOPle zPKn4Cbnrep3dUlED2_Oox=xr6-N69NTf>s+x?oK;cCJQo+`Vhv9MVpdSBkgj^V6$s zLnaPPOynGFDkAb0bcCSU>mJo@qC<&?NMlFq2*8!I_^kyM!bmuLt$GYCA2Q+kgQ}fJA1hIZU66={i4XxK+cP1lq4!7?CBj7A zmz<`6`5YSr7S?vA{@#`2e=Rw#@l!65e%<5E{8pH8B;OyWE=u@oE9Tz0d$J|}4&CM9#Y z{7mc98Zx_E_;4BPLrDXum+IvYGeaW|Q5&PLa1=(M`qeXQ_qn#6Amm9+f%+M|m$xQX zO0gX49j5Y8QO=GBE#F+?3X$pFI^*736ws$%lQntlEHJQ#BebH6(8lt~{x5qPytAqh zC5%%ZQtXz2kzn7m-hJh4J{A((w-xcup?ucZ^rNs|TQZ38E^NO5LYf;K%WZMpb2})z zL24UNLWqbAtsEXxoC%Pwia05*aG{47L~hqW-ejD7phDq(7bs>xD!(+>7_maE`Vy6U z^5_wb$Q*Udv3~uLt>rHxf6M8S@e!}A5+fDBMfNy)`a}F$kZwxh!$|ih;|y`6MYDkv zM=&J;{zi+0J2USa_McVtQ_V~v0rd*`BR_1RkddJb@08f1g8cFJIaf`6Nem|_{#iit zg<#G9(#!`Nl9)BjPM$F^Tt~hd%O$QCz7H!+WW0E5lBTj0z=e2!^yG!7a*_V@eBw{r zlL9MeKDw7v6ku-Dm5{nKG)A*|7)LDLR8wsV1f_Tt2t<;huPG%tE52L9<*~~T4=zb5 zR>tr2o_^TV)jzpXdQ|D%shD7VCwk8$z-gwq#m_ACLu%W+ne-AXy|uWBHOBlWpZ zTfz78A!aFM`K+(K&-UkX!O}#)UJ;v(dw`c;aWv6(_otQSwcSa#ZPk=|#Wgg%eQSR% zb#?zl+pG@X6`s)Q9JgyC)I}g^GR3D2{K=%H9kK(T$o?5?N&U#SuH(>~s?TZ>Oq^W=121dB5 zGxC_}q`?!lHsuw^FeCTLBrB!Ldfe{`kv=i0^HN}GJoqs28Ufj;I2lFnV3W-zb8P>!hE4-~ z^6K#k?wLq1FWl_m8tOuboz!w#-^^bd=g;{$=}(MYEd7ucm!jr~3bqz3dMp@Qr6#yE zVL#U_P~EZYOGdx*2_o1R;)ykWKhFRbw(TS^-MK&Z|9&kF=d&_%Q*W~0ckTFLTC5n~ zyqrcXh1x7o|8Qy7Eavdr%tThm*1`JmDR4mjOEn(Mzh#@0x}akLj%`yR`KHAt*)=>@ z`dYUVkj)t2X`zbauh{*-=GiDb_2Nt)YkU!8^b(r68HvWt>^P5?FD~>BZ)(HhZz)xc z%O#pm+$e5eP7r6oZYnM4cdLm@aGiV0`!5{u*X{pA1>c-ia*3+3o(X?%f324zWc;Nr zyL~bQgC!I*uxG#e&~i*Cna4M8-Ub@T$q6#oF{jtv&ZFuQ_+h+raJ8^Z#M}YR{)rZ$ zO7^v;CmnOt(8Sxbw&ex~G}kn@@+bJ*xz88>ZLxljib63|%Y`UQzOMA6zhORd0-xl! z{DH~iRpXF{Jr<{(Eb<%slMBbY6a55#v#eOk-xYsqNY{3bZuK_qBusBx$X6qW?Nq&X zbTP+@A>|YjuvM2Ze_Y=?uYOCnav}Olch{WaUmtkgzzE*9R(bzPNcHpR7`{w>w+I_5tgcaJ;HDpZYwvf8Ef3-7E@ z6Kwitl6Aef z%F0vS`u^N1_?(OhRo~jHtmiy)3J#@uPy&@T3KTZ&^4i6AkHJzX=tCn?#?V(C`LdQWcY zIy;c%K+mHAJOV_omi;T4PQGJr>aApVsw6Z`L^7|qaFoItAGI&=?!7x>$BOSOl}gw7 zdd&Pg+vSqM)&Uav3}9MmW{c<)PTbGV6Y+CR+TRtH{Nd`7R^@sYV;BBQj0r<`Q#lhq zZ6Wdx=f~ZZHk9zVwO8XtAI|=M|879Gp7Lo_+Zum2a;%j(yvr2(%(Iiadm3%NNv}=f zg9aSb`BQ(-9~kW;bh4OhAccCn_<-r1dSN+?dfL6v=VqxV2hXv4I=<$&)a!eFEz1-Y z6u>ogg(&ygkE8aHs?mT$MZoDT_fwpLyxN%o`S91B;$s>usM!m$A$7zQZ|G65WZJuE z0qEwts9 zL4lMC+};j9_7RA_mrD~jPg~F4vesD=yI;rxolXc8P`>E?xhX6N!ZA+-!sh10@`n&( zf|8WUmWvf9C^?{0tWsR*R#C-p{}7?5TGs#7{J{|0t#lLQ*^*l%IG}uJ$3E#d*}lT@ z>hoJ6Ip?R(LBs(K?fnedt_5*gIo9Ll))V57L4tSls;j2gDFcYO8&cGRh%}Pa4d;m* zLjfw=h-d&2Qx_IFVhyHg&|Ux8^~KkU$G7sIzSBCCGdFvj4 zx?gBKHxvfg1!)iRPa}d1MbzAvEkcNRRxdF_W11Aa$j*kBLPn_5FNT^RNt)BslUS)2 z_A7njl#Mx}c78LS8pyUNHhL9zaE)^zytHm$8UhHubmK0JmCl9%@3EV>q1ix;$Q23+ zaf-8Tef>|&i4!!O}eT%SP*yfu@ZuL%x|{NpgN1o9t=+-szyu7mneK%pT# zq*GXRp!Rk~H0?5E+Iu_i;n!{S=b9s^Y*LskWXq{_yCy6~3pe&%VL!J9R?%WvMq?pm zWo5acp=&%ohj!5_s;Wk-5`z%6#ZY0PDws&D;o+3-WAeogN^lI;_G8-U{yhi2sYmjg zRivaQwtzi>CZHJ3XzYf6u4;KVhH0sMJT~T4ke|Po^15*WxM{8;kLI0@)sKfo`K0Bp z^K?;9=-on-{}y~L^(}##JytU+nwuGhc_cA)+rzw%UriUb%V^>3`|8KMMi)vi@{EYy z!*H0x@hG31t0lEFjo!6)@ZBFzw#(?Xo@^ielIe-Q@lIQB@umJCR#o;bBokgYY5KKP zb?c7LwP~cv4 zYY;4szL<2IHCw0&wdM^3Qs7Zw=ZD(L&W|PafhFNgxL3Hcw3(g-b@ZtI)f7b~?Xl<6 z3fj#wvMKIiYb~`-gAdL6rIM`#IVwDGO$907RkR)1+>vcwk&LR93($aE^ac0d6S>ZkUW6yuDIqPSn;#dzkn$zSe8k+i7wraG&pT%K7K|Zak zSNb55+ZKNByR|w;471{!!_f|d1}RDYtR(v9H{rn}gCR~?wgxiU-17mh6$T2h0haN{ z;iIk4x&*?G6RxV&Tj{b3c*Ub+xKIV$^*{b%nV%DZnCC|?23N2zJbCo~2*M^I@A-3M z9g3h-A!4s|zHRTk-X^vVcJ;M??7WX;I0T$4=%0gY?!2!|>mF`P>&J}lCocp$?A-$E zV&i|Eo=2u@wWA-6Oi2fhS9wZ*m4r(yAqxrQwHHK(7+l(zO5N;IpdXS;uD?lV=n{giKtHC1lWj0u zFRynzW@?3Ae|tR|{;^I*Zif?mB-psnBAvjEi;B5uWo2(chDF``B#jya3imukc_$?e zbeNg_ z+nEgFj>O!7mk&CJ!hR`!dInLzy7|tj;MJ=m{uUbCwgPE{E*g0w^E7=x4w>=&{<7;1 z;Lk5~+h*A4;}21HVZo7fXltCN_^+-5DU}X=#?_$ zsfBOgEBdebBuyL#0?-#LBYv*Hn#CJxO>`2OrmiVn;f)@RozY31PpzAJiGhdllNTH! zBQ+7c`hMIQd2>xVx#!moHx?h)qx%eQLeBi!3-RLRF>)ZtH(n2}_9pDKv%lbc`bmTR zLcgpsHdD38mCt)UaN#;kMA+reCSJS*tvOVB-jjtrpA8a(Nlf?^%*olj2sr!rGlIy* z@eq;G-;grDu&IN|#IG`kAn+!rh@Q2P(XhAih&B;xvbcj7K3|bcr=#dM8}#hx#Hu z|H6qjo%K&`tILh3cxo3}ucP;~&M0&Ni>Be|PL7 z{^s;Ioe@g@PHn9^V<~puA1K;NuZI^mG>+(06&-L62$eqMh%jSgSik|8C+$iRT-~}@ zBR?(5gxBftKC1FgO7J_N(ZoLmtjC~loSxP)oOa^IfYv}5c=>cU)V{=f|29J_h*(x7 z@=eFmhJEI*INBQV>q~x4h~>^aeraW)TN$8T;z=wpP5U$*))@{ol@-E_oN$wSHZdolMCJ9Pk8D$ohrYx9GV|dVKqNU z>j*BmU{Vlkmr8+%H9FMUk(spou)>x{} z9rlI>#{8&T4rCg@=m%Y~1a3w2+b2C`3^3)WJuw^?b>BtcMseXz>6UKRS=)39?TQ?W z{v7d^7n8I-AUnBGQKw~G^_mDBecnXpCy}wKt}9Tv1KMim@T4^9X46b=c{%n?ulFwE z)hie8#6p|za_mx=P^TdH?eOGXRe3>K(0TN;fx292y8!Jg37a>(?zmzk${>3$NVH|BD#--W)-Buc;F}S@ImcdsjhAbgt0703bQSFy@K))tkreo|bNsAq)!;bZzZn zG{=&4HRHlhlTW-mSr=wc*~T=>MfDLb2C<(Vb=9-mIRS$?MiCJVLKfEM<5gq%Mp#9U zZB_#?f*i|eGreloqqZ6#6~Ne+joaQh+tXgZ^XmQd>9VhRmA*ZIPkcBW2;DX8P_wy{ zVYzuDah&^>6K>^1*_U_L)tG|6Y&SEupStg9f~Q}g>&5kInmPgZcssP5`>GWU9Qx=D zgGA+=fH;pt&jk7~&XfKim2cut=sws8_BzF1va!&T_i1i1^DofJCvo=xm~HKgokT&< zo)ht8@1V}fTYnR<)vDo^8uGHRGlmf6Q&qsWD3htPAc$5(Z8^#bh~=wKtWKn*H_0D=Yfl^l)z(gB5AC=m77FX^%AmE2&97 z*dk8TmsF+~CP)Q%c!{QB&?9g~2B)c;Y;7MK6F+hojO?5=X&>z_5W{Os2obKhKVzeK zCxH1#GhWDOk4=#Pmxi7)p>ygG*uvzM(-G`stQ@;@=%{*pVlqu#qoTT8BO+toKIq}yvQ|5@-$ z{k4{Q9r~>~SV#Hyy8LS$!s*duw%gpr&b9-H<1o2Pe+lO5W~}Msi4p*-=neubMF~)p zKv^g4)|fcJYV&YfFiOeqlLejCpKz>i1ueJ?3G0#p(j@@jP+w63g3fu9+KXww!L}|C zySd*30q6E5z!_Zu=Pd|ZQqO})K)>UC1M*Aot2}OV8pk71918>pVI?r}D?%(jP4OW) z0-d2Vj*eftC4TNVT)m8Umj?gX2X=HTFN3$Q?SGPK)r1z{6F8Z9YRYZ!IEapij{gQj zO{S}y2*^m&iGcO-_7 zZvY?qpuxe&d&7aro+u7K3}on;BME@G+Si=j$s|dg*%sCJHbGP#3=`>`Lnxq@akx~k z1pOwmG#H(o+t&S4Kl!J_NxfS%NMwzC@ugCN2I+>Hit15B*Y@|O`}G>md}SDa>pPSz z-8WiOF1}`^@mi#KQ!(bML)J8Oqo6AONq4S|uGf#ry_;wX-=;cCN!vG6=Bcnh^MJ2rOJ;~5y|hS*l6Qka2EC5393iB&)2)=J%?gsz|g`Yq!DG5@uoP*DjFw^YpR z3kAKeloY96$?SlHnE&@zV!rPT0lB`(^>HnTmTfM$a~^`z+`8zB%U+T_^J{MziU@bq zBiDkX1Vl-frDRCfABN!JrE3N!H%itywjoF%TSDxw`f6!`uxu`M{>YbCAK3w>12|<= zX4xXHR@3=qs^$gJ__UK+nT_=zio^0;qEP0du+;Hs>TLx+ z=mCB`qWKs`7f;6+s_pEE@WWi1t(mvS{PGm>aWyKSqt*#C{Zf}JRGXHR7QP^@X)ur~ ze$ivPtSSeBpaXM*QMIc(T2;ksF%bi8e(=xPmf7#Z!VF-%&>x%HXjJw0oEe{y0s#l* z_xM-8)+&^CbxSgU9W#`u{f5p;i$E=@Z2c6AT%YxR(AW6*j#1j=td)3SJl7@zqw|7T zU#Z(Pr_Sn$D}S6~l=~#tpoi|{3~RYz;a;?7OBb}euDY=|1N8rid4}z4oo6eo%&%A# zU>6Tg(xo85&!~EBx#j&OeI%oI6Mik+Vw{nnu7ovUH4w}%G!%STjhUJBIH6Z2x)vDK zT7&#B@yk*LDFY%VIutw><4(y6md8IyBb~G_8b`bOX7J3qE;{d|y z_@3)62M`m~>w@vAJ*;Y@fo&OuT`4ETbA^Urbhe<1d20o8##!!Z^Fcfw4Wj1pu7&c9 zDV~ZktkjRUZRv2s@Y}v;$<%2lP1}1ck`*B-*4-Z1ykguV%J~FMZ(I2QADRXzk?hw z3|Qj`+4%)BAwcUV zB8h9n@XBioVQ|-vvt^ts;r&gvjxhe9(_8FQ|LiyL&Kx! z!|m8)i5cIauMfKobreobJch&zK4jr|6V$5lxb*wO#TD~)sI5lFzzZD=XORsAYxJR) zr~+c7!90rupoN!RDKHd<0ZPPuL#gk18e+^;7+~1xaXg^(^8>6CU}&$A_?zp#x6;8k zgN;saS54oLkqyEF_9v60z^qJ4%1PpW|Ep&EHdPIQL&*f;xs^-ZK7agJ{s2PksR{i_ zseNgUV;fc$$8>D~C5{5eu(oa-EKGv)QjNblpPOpg+=hmT?c29IMD9NI=HunrU6mSRY^r48 zTa4uv5^yP`YwL4AwTN}Q!XkSv0Y@eCyck)Q4^;p!_4)l%LpOzd-d_wiv#ih3x^#`m_;P1f{P44wuA=P(xz?@j>g}f_HlW%*Pz%_^il%mxw{d|43b#*BoRqAlB z_q3QM+Vaj5LC&KKtJjTl_C}%fP``|+6oXmN)=|xRrJqMNX-Yw(n*06rpTaQ|5V&h^ z1G;xmFb$G$B6Y)&YdIo<{2J~M#;zi7bnMjH+e1!@-dBMg492SUWcSz zmIN5Yz6qINF_|f=Zr_@o$c>MeQ`gYY6Q>tla&Xvtchjl#eg47EY0^PW&uKD28wzP# zf-KIaWpnu$AP$%?JcqyyX5z%Ke5F>2rqN-~mJUDhCMU%Sz-JV2ZSoBDtt_$4(n{yP;Mp8nqK?Fwwd_#z@*k<*W41O>n-3JA;wzO zwwCdE!)w%b-QD!)9B{@mo-iDW-9sO^FN+bZ7q#l>FyYeuv>m$=285nQ{j}@kZaFr5gk5zgd6BHr|3$4Ae|Em8V`0; zZ+$FB?yG+P_0cT?Jd582_>|Bw`ASJ|KRo7?gpgWR>X|NQph7P1D8KnS;9yx-1GPHO z-KY&pjB*oC{!3^Zb0Xwfw93MI#5n|NrDf~SG9u_RzVvjrxD!F3VCw>**0ji(Bk`x? zmiUlf{sDQ(^L}f{8s*N4pu@|Nu{TdYb}Et-kG;b3j9fi&quZK})+N{ajG)0g1Mf&4l~Ebb04wmW#rGoJ%A*9` zR~o99zTb8Cq42B`x=hjjgMo%Uz?2Zew%*pia)~jcvdmTD#Ytxq*hncqhMZ6kEeKZhIs?;P&H=ykbv@16U?Eg9}BAz4jj6Px1+ z?}u}hZUH}6mb=sW_qw@oQj>rJ`O5-2)-Rdo8OUhF_v<2H*8--T{)n#}<{Ag9b)O_=a&l@4 zt&c%IVBvv4xK)kUCg>;oeUQcSVhTY0+R7sGt4Vurq;__8SjH`Ub9-{oGB|cYMw{Za zw57&Dy4anPASvG@?vSo1*WUd=wdT&EBp9i(+>QN=Gt9n)@F^VC(rZRO8Jod$Y^YMaF?>_<27W1A17Mj#;d1ReH*E9nTfS1 z=8(U($Q>2``KAxwIvNum2nPY(iqP$sT<7w~QYaPgIz8o-(&bYaNC8GvIFd`;2CV%) zUnEBbw($IdM(tf@HdyuL#Q*`gS1rw3{=(b>AsrC5B9^sbwR5ke!fYR@GgGW>f-Ih} z*DkBhuh!yeRc5II5?(ErwIW?|8t%UeG#nbX9m{RG_Vrm_em>OSA6vD3ztij_u`?ry z7{65JRCsKTuYADW=8*Y>&V!L5y&_#XxdSDaac2#H-y!l}N*ed`mZYD>o*@ath{dRi8irJRe56uZO-8_BYI)u_ghF<0a5YHO2%>!W@RY<~ zwLnSQ=;{7qmWQNZPQ*c=D)-oDmQYI_8Y7#>?Y|7zYpcQ!g)>x?Mx=a%bXZ*2CYVfA zTJ)S>B6$Cm`~Vnwe;2GOC%5CFIxxxaGWApMVTY#z*z1e8B`Y8)Gl5l69t4qo^j}qq zqua(aF>y^ny}O#Vr>w`0iCQCzX4!1Y>kJK^p>&#bj!&7SAM+vHA8(1#8|!|0!}?owZhAu%l5Al%9y1YO;^X5q_MICjTfYgUZ;vDd+(*1( z*JnxU_orpQ*;SUtCP|wuWXzD-V5J>WTr}zn=tb@Jbsno~(Ty*|yE8Q-B13O_nd>*k z8f?D)DZ}iJ5u{gjhtKKj3*$#o)hic7_-LJB@w}33a?>hPPzH5;#{t1j=OGWYfBx5By@Rq>eX0C^YhMrM!jn1yV#8w-utZmQ3 zBc>W6V~XnTA8SOVZYHZIyWyQH_>VzfOEg+beI%;WcHDNHIzw}DpJIq}rVF5!Nwb1T zS6@E4m@k_6GNk0%xW1Bn%%^)850A=l$0K`(ic^8xPE<4TS?SDvk7bch&D;yn&VeaP z^S)Hv7z_JOQk^6im*S+7Rq5y9Y`{Z&Dq56|`leu}(>QWoac6;51TJr9gVz(-QdRHD zZfb}~j{v5Uvv_ogUf@jJOLB2)WvU{*(QCGd)yzm@r`>wtkHA^^RSbIGK700}uCFwQ zmcCRC>K(CEU-olMy|~w}Rn>$$cNbAsKe0A`FGOB$$0QQZb(~EHIX+jZ^MZl^z6L|s zqow=c+APUmXWJ#3IA>%;Ff)xHD6k|@TTmpwS<Bbz5V;ws-!P`&r))w_Sp~N3i7%*vxXnuqv zyGC}GJ>#?9rWp!$^)2=?$F98ru6W_?!@X~KTY(Of$o00E<`_jwmoGSPg>L&j23>nX}`n!vqA*6$4Tq_PLxUd=wcgTuZ zxy!U;W(F^xM`nqVe!B(4VkrgA3j#aph-43cew^V;w~L*3Mhds$Xz*yi3!xLT*235CQ>}IhH*{v2AG~!3^5j#_%?wU zXF^}JA$shj2(6e$=A9V*FDA0@h(C`=t`hia!`}_s)BXfhcE5@SH}p*}M+-KqZO`k{ zjGOj*8yf)ueH-)T(M0kWXYI;Kj+f4UqePQC-_cy~ePdg?A!tLL_AAaBC<|b_8%KKB zj#|-^d`t<{XprwkqzW+6=eJ9)ZUvnD5G~Vb0A>t5eUQ#A4sYJ7s|p19TgMp4o@c}0 zWjZNa9_c=o<26QD`tz7AwbM=M596`6$T}GPeRJfOe8e*1npe@<50Cd7LNqO*m7eoZ zB760qgLOhkl{0q!n#t*jZr;Cr0Qee&e=!Diw0 zE^SsLQyPr%Z-)>WD0eYi;xEa2G!|l~BwEaH?R~Y@vGv|0K_%I%l^gVg*KJ!9psClY z9c=!lNx+Y+inQ!#O1+<31XLpgk(-8_8xl){9vNP4l+XzsA<(c9p<2_<_LDEae(G+V zGc?^U{L=Yu zF8_B3rbgz|5yA^T?H)>t?YyqOxhkxPS8dG{&7=XQ@Tr+k_JipHK3K4!>NF2i!lS~zwW1K#7JG~&es?n1{>#%5|s8=Cp)m^D?_T5l9G6(4SzaKu(@5|zOcVZc3xiDe zgU;^^o}@4+4z)FuXlLp>->ZPTb9E&(bJRHDop1a(47X}&7|9Ana!V5gaeqbNaTnii z+1verPb?md<~1D7R|9J3F16@(K~rO|@f~W?!(CPu9BcmEBN}?u1?Qwus}(i#?X^>d zDZ#6}N_%+nu3A$fdo*`8u{+dk)|0$sQWEEX-6cP+glu=xA zM&8degb-t3=_u>LW)-YT9M+)2I(U%uIEB=+9iW}2J{l||wNGy-n=6977HJFSR3r}A z#sx=1NUyOgm49@*u~hlnio;tlueA{bLH4XPy1VDJaBvH+aL+ zJaxEU`Yw=SG`zqgjvM%7D`J~Qelh_(~VQO(l zy|)ITraD-ljgPnaOMMbe+(02DZH?N1ROSZ#k%*z5qI#;)3z7=j;Hv3k^A=Yy^ZDUs>x1@Yh7Q!in_wOd@Z91O#xd5b3 zM2}IHv8OeoY%|ng^}NVIImkzC2oo)=%m`cvT&*AEC9ts(v-A!@(BmKmI zYF8y+4Hsa@>gKBPQ|&GEl13hjEZm;gpNLqY5U`rXcgzydW74Ow5K^1@3Su37k`|{o zi=No>bdpZyj11^R@@Nb~+z@A}q<^t8kv5}`ZS(z09*{)og>_jCm$_tHQYP!KSN_J_ zos*tPH2W30i$zx{nEq1aSukt_{Fev{-Va_6o%q1nmAP?=yRFaYV23vq{j zkIUUZAsE(V$<6SdE-bt2}JYEX8on7xYNOVj0M} zWk(GTQ$12#|65GbVD73WT|mB@&@!B4Y>ABL%|T9!oX*w9wQVqfAWe6c@aHDbg##AN zdyHp`qrD_{D#G#J{Z80GjUGMPQypGVmWG}kpRUGjHp6gp3Eqchk?iI4q zMM3G8-7M>y4?cEZ0rK5Qp)2Ey%}PPN2WneSOH1$*&%MC!j>wqUW&7Jl;up` zzMPdnBYk|H6VBpTqzz^-shr_uB~27wTp27V0^~z&zC3}pH^LL_+#eP^~n09RC(r`ob)Wi0Op&S)V>E9`;>3>m17buyDt!q zt-iPg;=b?eS&!UkJGyeY<3m@v%EbLcY<4gm+90{10kgjTEql^OTk&k)XoA@?8(THZ zN3~2u&wbSx1)mK-j;r%w}CrP9n7p)asYk4N}$gyuMi_Y zsK5EO0w(gO9w~e9VK;_UiN;Ke$s~;`uDF`K=$~Q9CAL%LZ2(T!QItKAbkDB9+OoTF zGZKzkh~Kgh7}g^O$AsHrf|L8Y=_4uyeLXz$A{g(@k#{Okl~m?Yaa1gJwzb?NuB2>Y z083u9TE_^z_#q+$S=;si_#|m!yzYNOuz+E@w3qb1(aVL-e0SXalnAe;pj zJxu3pGfJU`?*SX9K#?ffaRD-6zx!`y%&V9EB;19*p!ZL+$nF;S zV%xr!VmqSZ+8(!jadag6{xI=djX=bpB~`qVN|W7a^RYU8D^bHu51v+t0~Z)&;^>FW z-RJg0Fjw0#{D?71b(Pc^&KFG8o3_1--6wXazi%9jV?CbG;MIaw+*Rqdb1J63?!rJR zIT7TE50qVKWzV!=0caiRM}XZwEwzae@b|ByocR44;_jcZC~Ck9YN?c=W(F3wU9M=s zuo7dcNi&yiel^8>(cj%aRw-YZo2*0atPBuG9tuhZ_az_EOT_McEkA`eP)P@-wwhn> zkyDcE`t5?w?uI}`g#;T=RQ9HH+-uv`fE_`RRb#rNBx1Apvl72^j};sf-o2yA7-Jo5 znZ!nIy+b#Qu|$svw>4o`Rsy$I<^O5kJ@wRl>B;;t8h>9%cY79pC2iek0U>7ER z3?Er=d@)~G>DNDt$1XJpH7?yrKlR)@(AUfXx69g8$ux!YXu1ky6zgn~yMzH8q?DJ3 zO^-ri>~R~y<0B)qaDuKOoM&@#jFOs+=1Puuc&_J(AJAUDpungQeflEwbKC;$f|u}@ zV9tc}68Q@kfwms08^xzuB|Dm0b%{pg?)Bn50lKi$9bc%?}iE=cO#oRs3DeyrV^ zxO6`Ae!udpA9eqffAN{Qo8zPVYn?z4yi0Y_gGx1FX-*uhyD^`4CaaO$Vkg15);dq^ zdsxJ}Cw%VJ*S1_ET#cc0fl0L(e1gU315LX{@jA5MG>oH z$@c@8>L>m9;g+9}Qn|2K!td8bG_lYNiAoSDvGM)zCd8xanf(wGbw5WXC_*q)npzge zos8+)koec#31{ALZ|$R=8Y%z2nJxZu1=&DqC5~g7Tq&FIHB(nADpSm>g8S_M_0JG) zqu3*7MG;z^e26T}aoE}rxP6|!_SFX>$IK^J2iIsl+7^J^KEJ=s5o{9>%BCkJ54?C` z3$;uq_&yic>6|Zc!Y*l&cwPKJ<^b*O>gFnxDavBa<$m>S-0$#JAd$=E+vs}ccuWoSKuAmq$d z_ocwg{7Iq-?)Y&Ndc*mXI7PVwRpA0>O^4L$MNi3{UHkV#khtv`Q!Z6Sm&iv>;$Rn+ zda6y0Oi~!l+r6YATY5(0+QGb@R$Y~hi}*_z3^?Z6E|Zyb%v8LM&aOOW+D(<^$=jm5 z$ds;rBT`#rg^{!r zUxYt~2Wh(n79)sYD%JyK?}J(hf3(@gjlGY4It`FCT*k4SxzDQ&w6o@JX|QOgy@UPQ z`Qy=-i(oL~c3GuA->FwdvI!+1#`-cH@qF!APHNcqBe3Z^itX7)>~V5=XBt4}e$;e` z@{=%JzdpWbX(5hW%1M0NBA8V9oE&-hQ`GVqv{YfLWNy4@?_sWA1v$@Rnf0(~8e>@q z)mNj;fL&o7fs2dMdYQ<7q`d8smecK(E@G3YDzN>&1g^pZBzN|OBH}9G`%rs5IyN5J zj~!=*Z72#XjJ|IS(QFM=hg~!3i|etl`jpn6if|U#jqGqRO#8^Nt9(22tIK>P-Jn4iI(QyTI#zA#=)o)(Fb=H%v9AX zT$O;(`|WXjeSe^X2D-9t^t%4v4d8dSxc3TZOo($t6;l6SYDpDd;mXzPwgbUzm+v2#HSMOhV4}bDkFthplGBEAf0V>SR?@sArtyvcgow{0vfaOluH$Nxh|tm^FjYBDPZ#3y zRms;W!npZ|M(A_5@fQ8pqZ>g(Z*pC#6+2%>g5wrylAbUZrLwR-LT=7)7x#MleX!zdbI&;}LeA<1B#K>GRhj#|Ibm9e5P zt1ieHg=ZDK2==Wd4^d?2(OP72(MpAf+3q%z8uYkKBY-lRGN(MywoA=O!q*Td2DgI3 zcT#FmVd(zy=HMdMH)WZmc}gXiR#vRj+sG{6eJD4D`CET1usI3AV$EiJW%PN{YJ8pl z9E)ihMakuJr9vg2zLoJzpT)>a`fw0m$QAcUQE>DK_uK1GsimViQz9c#Ll7lK2p3pX zO>zQh`QV7OVTqstBz;Q9MOYSrd7PWv@#wF?k|gQd(5~dkHV!mv&cQ0ujv7F`Qm*2I z;U$qI8UoV|h=tSKxEc2OR6vzXDqW|v7lL#>C{@w&&R)3zJPoI>Tr3VW#(u+c+8c9= zL*e;jFIE{3mO30VeRir?B{X*{u?wV}@vjAqj*%6_MG#JRH$Wrs49m3ip*}_Bw#BX! zE(Olz>4~yxQ4jAa5Gts5PWQuya?Qgq0*BRd=a}KwpC{U5P8+E9nRkCF@Pn_M;JROT zW{4&m?{GF+iBWeHppJ%3?~z-gQUNO-`S3n$&h&2n9%~#dLG18W^b`Qg8eo?D+ug*q z+94u^PZ47xQp`;1$XgFW?F$qb`n1;607697xY~`_yRL!d?6O#lplzfYN}8D_hksq| z*#lCVO+G%9tfy40->=vSsr=v?w|)H$cS51n^aP=CPDiIvPA`OVN`q!$lW4OsNPm4} zJRim$ZHHTg==I*|nH zR8e?Ob!YNZ3Jss6fJJ^=QXXBY7mo>Jj}dA#vG`vKx<4F~rF)@lhe%0spN09pMCC@# ze4D3#I5MBWMQ0<`!wWYNn&Uf;ZfV!E$)Eb9oJk?48Z^VJ`iA{x1edKn4}}O$5bhrm zunm08>!8zzxeX%Eu~Wnt7JF#Xr~Hu$pnDq{64n!M7J&Tnp@!Usr{!`dwgg1AuCw3` zCuFy9UPHXwp$alHk<(fPyQ=|gU^9dhbm4<)4ZRr2m(iMxy)u*NiCD1`2Zfzut6W!w zp(6Zcja@l;L4d7&{x)x(8#iiEd*N4VVu#(c!Q_@z6+o72!#HC^pA_-XPFgqF% zxXkJLy4=&_t3nNJJ|CIW+PvY7Iv~W}jLR&Lm>y*hGnQzZQSR#8mX2%9L~L?um|Byg zuiEGM3&AkIPGzX9?a?n~MjHl@3$RsoYB?6K7udaL;I{Y$;N>JV2)OYA`5vxC` zt)<$3*$Q&VG=6pXR;;{8xMGF;C82JJI_Vi(X*h49UIeQ-ZsK+=f8`K01t@bHTif;Ger+w4N{t9i%e67Mr2zGk zhF=A;iG2j}{4pG?!7U%VXn)f>tv!x+@!J`Rk}q@1E7SC3%FZX*OZXdj|HWi-_?nRC zl7*7gGDgMJBLt6MtIaaZI@a%>w0fLJ7NwcCX0hTHEEep5f`%I=KCPyGvWjb#L?g0u zg(M`a4<=K?{0q-*z~#oUS?WTrA@Tn1qJ*TC#+I*SdeSAzC5~rZP|>4Q7aK2J&;{>( zN!Zv7b~3!`VK8 z4N0ETD7;3{lJQ7$1NY?CpuF?QO*G}qKie|ukqXRL)?Ht|(nMc`Hgdc5n*~$Tx!qw* z!?t!jnv-axE$bXpl()q@{%FVFvDf`}1+z&$A*)9jn(|@m(x0k8l2u}@+VA`JEeBJ4 zu_N&)3~@;8YQv=1%6D{C`{5pl0hrh%L{XY=e<0bB3*?>E+@}?3o#C2F&gDj!Lwcj-sTb6e z12;tGR`t#;Unwi2A*_e7x$EP`hVkO`ER;p}$^m5I+)5*_yb;@d6!p5@d4*hLfF;Kr zJVfC!Z4bF-=f(dbs|wwDosmfUmLq*EQrIq>_Sux(oObG-^%h%d@>g4^5-q6m)biaT z?ve4t{XIsoqM`HmAjrpghHAnfIti*nH_}tO&2+070A$6_ndrwbo$Hm!=l6J2clHDc z)Z~${c#|3bJ6f{FgOZPeVBW74rZ{nN82KjkEN!=PWQP=(mrp}xpS)NtL{QU6z; zxgh1#LetJ6WjhjuFX+be4I^e#rCinQ(XI+pFW*>gr$7pS2o;x9_dXsks&ZeQZ-Jp= z`ZS4ous%Kd$T=$+f73V3Eur_xSAN=`^XJzA(qOfUM1A7em#Q>LLZHkyDUsQjF0Lp; zKU{5gY}Tgro@KyNcvDg8ozyLzihGSAC%^82AeVpiqEw_taZ*?Q;_IQkU$Zj6_yAdU zhay@l)y8_Y>^WTI8$|}2kcM{sD3e2=t zB>{PriD5wvI)-$~QZ~=v+962M=Uw%?YHaU;dtVjKW5-Bi*J+?bZrfE#tW3SBD%PAR zl&s!jIQ3x&h20FbTQYj5`GOT5*1;m=Bu2PLB0*T)Njq0L%ShpdS&4%I3w#Q zVj}Lp31i8yIWlmGt1g82n*DnMrW#DOZM5GhFKg*~d{Eo69}X$cc+%t`eCEv?5pi2SDc!rI8%s;m>LCwu6NuV~Wtb9WvuNyP-nK;MV#> zAe!M>RH7?wHBJo(QaWp#GPFuT)m1p>?}~V_2U^Xsmj&W4V`ONnjC=PkD=Sxw2QuH2 zHRa@v7hUIq#7@#Urpn)Q>#wv~@2us=+e_WhKY>wi4covx6@3V1M-@4|1kjM-j0`Z> z--D+A!EcR6_Mh@~r5OGTYE>E>Fs?ir{`q&j`Mcz0Lz0$&v_`JZyealx>&=ja(-zbN z)X4ar@FsSV@uj57tjzEH{61bL$9-IC)txZHJg68OsfSl*j2)Nd(m%%21Ai{WSq&@E`bDW`;$E_OAo4rKTm?#G|tta6Om?L4H9zA)Iik zEail0iyvBN$t;do&VtLNy#&UOb^TL;DrQ&EXR_{I$!mv{}(Mo zos|_)n6@IoB*4s{n7{)zC@4G%r0h5uSoyeKe^+iW9|33P}Ge{?LWU# zcWC-uOx2>Sojz{j13uw0wEQk9O_nAQHvhb@@Z3Ho~C{u;DU|NKY`=_ zXHI91LaeII9EK|cb&!(dJqgu_ou_4Q+c}|E)`2{HxJXI;;OtT#2#an&j#>Z2Z>nk7 zLhtB;WnX~(#>800tya7U7BwK({vb}@R7NZGX&whmJ(Wdnww>Sp*>t z&|P{iXR07m%+R5T+)OgL?|$gllJ zR|5{~9>?V&N?_>NY{}`~sp)bC@ptA>!oxwtif0H74T_VR)mp|Z)87HJ1wh<}H(3X0AO~}jv>YRHGfBru!{uGKzSribM>E26l0#m%w|FNt3r+(bj zJ%NL%ZgFokP`UHZ4IRsWFZ-b*acDy!hjq?muMT`1tRyRC87mzN7BGkGsG8&{CO9 z;A6`*{vyBrfj*Vp_=i0v9!0F{YX6gEvNjYeRY`rE)5r-s_>LbaTK{7z&+s1%{eJiF zzi(+o(Pjr$4$#q@pK1|MpUVXEnkM!CbUD)?0|k;Cuzo#+1%2wQBb2uZkZ)$+ z_`V$1T|2hrAN=$okm6RL#-r!>AuHhK9v`STpOCPx+R~DW*DIrfxNlp+-?3<=qbzKn z7X$ao_unE{@luwm#qZ#K{^6=+)E&Q~dkx3RgcwYe9*j#kZcoUmJmUWBq2~(%VR^Q! zS36`ts7+<{jyS0LFrKYJC7>H4s!C4O4~|d=qrDNeaXIv>EAE}WqjL_83y449MeA63laz2Cd?=Ju*HGXK3RV>zZl~Y zOmoIomy=xnC4@4%WV(07nYvgl{PM85Eo=l!N z%?a|r&+5>KV}1s72`SsDd;-)jOgfN*G~4Gm^u5h=4p zbakB{N;G)+K5O@-(2CfYG0_^ldG`lmoN#f9eTSIzx6+-8lm7qVoSckv4r0SOW@XpS zN)NVAjpMGv7NNrBeBHMNXA04 z0ma=-CRgdn12xTfi*aX|%YQ`08!ST`V72#YL!bb!)tYLO57H|F;AqKlz!xjDfst3{ zL~jL8f%AKy#@Z0-;3v@fyWY$HaZ)lzQ+h!6!2eXd|4k47AD&V}e}zE<&y;$nuZI5M z+zt5~KW&LBurI*}>gED?p1FPYVkv+Ng(5orJ;RM`sV7k779u7yAkAA3>N*DK^vOWY z1wvIldI>x|5n5HQ_G6}F7C-Hl%>E8|l{Y*zqBimL4o{uiFQmG=m3bc6T@XXIb~wu# znsX)t_rQ2dEw}j$g4ZS^OZHiaE4p>W%Z~ba`Bqv29nx%CW>l`6{L{v&ssEfe2}i3% zs_q3w>0D>gJ||q+A7#f@rat9%gJVps{BSIdP|A#F?#BtqkssuE?)Yhe*hR2sj`P_=F$4@~=|c&J(rXVY&~SH{-@J)*=r zv?1?MbbWJAuaSKVzO~^*_FIiy!d!-DE-SgD5rx&gR9Z2R`{)$lG~k!E@O+{$ptfZq zdpm2wr^54<^^3!S?ckVaZZUy}p$lxZ=BvNK`LMGN(2-olERMO)MB4tL*1k})92T?W zhH2Nb4CYJ!8Pzyz{ot;u5yZFEu*p^GSADQzV3Xn9tBwV@E9*`ep2B?T8o7~LR&@V} zF$B{RAnuS3wyOX{U|dUaH-w-kK;Lh@TUvp zflZjx(!mqIPgy^I=ehBTDQrmjq{BXs1IOnP^fJf5`ljilGL|%H)VR z&%7wlGj}qC!$;^HdbWTxA=f8n{hg-^!TZQRZW}1OMVSj1ztaXRx`!qJGj}@i(vsCJ zrJuTdTX7pui103YLwo*l`j_f(mV-f$T3#WdfANjctJWxe?6WkL2=HaE^S)$JM-KiL zFqB;JVk6Y?S#+)Ge(aEcnInBmrP*Vltfj9hp$Hws`@f*!G|mKNC>tzTIE(PAf~cA# zsxo%8e@33J&L@hY1Yw+GFWs+fxm@ZIKAGkHB#4|aE87`unqUa5!7u|)q!wauji_t;G0xKE}wivR_NK6TDA#s zHS}`ImMy^topF^#=N*boKgQg4cQ;|TWdu1cbl3jv0zFym?Imf*(f7)4$$nYFYZX5>Y(2|xe|7JU?llHs(tmn0FeN;!I%pkr+0881=(!pJK@^E^y#?w13 zvdHykF!gdgPYTBC)dY3~N}2ghzyF#F>sjqT65|Xlf2Oxgvq2pRGly_+&?Actd1OoO zc3+rxtL?NSlOhN-883Q1K{9C=B39q%b=a(;_uz%!^KB^>-@H!@c+2*O$Z*OQCNkl~ zQL+vyZxPG|P#c!}pFFeuFRx<-;oM12IfWQvHC#hCkE=L75KW&$r_Q`}D!>mt5( z^;WU>54jM}KiKQg^hblc!9uCHB1$_%^-pJO^U7k{oXp?;ccM3A0^ue1WW#39W}MJm zfc3vS4T0|8ZmbAZ@Oh`|kcQhUQwWUc&6~fP2ZQaz4I_N2ot8 zvm|*o|A}DYH$(rtqxhf5<9A3YZmsG+(f08x|6iPXKP_T8YQ_^!l(x1EGF6&Fkg{On zp{m=;uo`cCIY*_b%HwT*IiC-435Ff;T*8t^?2q*mfvuA*BymnOhGM~oA>wXCLj zM2|52SA+%S763U6txp9$t;1G`!cZR%_Xhd=uvBtOaGURcK8_poEsqHglSQ?uIkHM9 zg(-8iuOQKCz+}8X`}bd}6Q!A;PcF!^UFDd(zIm}Ga`_XkopEizckxRFuAp=1d;Y4w`=OI;GXcQl@O0y?WD2)NbIiNu`%b2drQXt5bgNT?!5!VmURi?3 zYd5)b;`cjMiT+vYm1%a=?oa&CUhCdhABOs11(z@xPCw(+bCgacsG&*avFG#BnO}%n zbl_64q(NT*F`$1VI0d(sv*yg8i^BAl8A7yo>pSC9L|Jwj7GXf4V63L8F7_YGB}pcW(Pf*y6G=Q zY6EL=K|Q(#^?Y|TfbPE|avk+4yuA2RchY>gTWv(#+(}M+hekb{e*qJHF9M4Wf%aBF zJ{LxD2r5b9-Q!FD`t1DPwXA`{;Hxzf;54F3e!u zfR&^=-x@G4bJCw#jxzy2l>3YjW76 z#xkz0F1oGNh27505T468$Fu9LDv|+WRcw6A3+8a+`li+XJH;wzNUNyx<%ARX_o0yi zeY#R}BLP>QY&g2+I?*{Sxjkrk=MQRi(5b3GEXOr;X1lZ&iObll!J9H+iZ|O*9eSsA zt7Vyy1SQS09(R3a=IlI~_Dm7ls13wcCV8DY{$#U0(+Hw`P2~S6D^pn^cg2nx>60Y` z|F*F4;bVFUue?CNj^%+MzSYR{iz+`>3ktB2Wpb@&p_AADyd=S8!ZSjVJuf%g13|JD z=tz0eOIgvWILK0l3M@P2Hib(~H-%9&Ua(Rh_N?~IH~L8s9Ut!*O5$u!z<2IR%&$boHGt0vroniPFf5FI||00!6J`cyFJiwzChYqBcT%l0Q4VU85nW zDVzTkFoA6@JY~`gj#+I?AZ~TkuBQ2No75G(WtJ?}Bw_D0FjO2|v2_>;hO#{Q@+$9s zT7x$?f23ZG8i3Q@xC6Oberlwzme`6U=#WZ^)f`&7?g!b&en#lO0OU0StqK?7mrq%P zYa#z6l!x+vW;vvP{DfSP(*LZq{%?iX|Hr2@7P3;3P$(RtP(J0zcBTJ#Ah~PD{#6&F z(%K`ZlGD=DdA(+gKLo*Cc%eb#&%{*jSf2c^K<1pb;EyI&`6esw5J1{ZMIg>y_CoB7 zaVF8S`)fBe7$iR4H8Pv=Rey=XZbqT|^Me}d{iia#Z)DJZ*5u3kgxdEvYccK8a)g+c#U8qWP4&+aO~#O>8E%s=j|4;#%<)! zGIza5J%0-@RW#WMaV|hT%>a?gwI%OGDm(b?OFiieMzUSGy_Jnl_3zv>zCE(5&c5^N zo$GI`zc*1I56zxvzjbBJEnwp76L&6$Hv?L0x$v+>=d9Mil;dIImEWhFe~8A7S0NWt z0kc!Qmeg#7k_ zvAJR*zyEd~6{w_F;YF)|HOW#S@N6E{_SXvG6B*v)$8+CERRdx(SPHGDV)oLFDvgU1 zk_0%(MSI&m>4b0ah~qJ6ZJ zCFyq5FV?6J%j`GktVD-(z-So34w|?%d%}zw9^QgpB?sjg7!zvXkLdTk^*q85BqA4r z@f9L2OwX8(nfE>ze%C}_w;4~xJv&nN@Zl3(m^U>{Z%i20{HLE=k*vsZu{0mw=X*c& z^nSuo&a1Pl9Qx|U+2vZFE|EP@VB(?*K=U#;+ymHzyB)>Ik_(-o}NWOYMEOq0Mej> zHVBM4TGSr05S{EJzx#9u)mq7lTM=)+^@asoc^n#3tqp9+VDT<%d}`rWH1;mEw#=mi zY9*6R@KuM^tntW6=Uo-MWD&_Y1yuO8xn9&E!BAco9gZVHWCAEvpP00+-Fxg5czZUx0yQE#)rBcB8Ib?RJ2US$xbmTYa=>6EBPl<35z~;d^N_%9mo$ zwKe1ANoHnOhiM)a4HHDa=f74CStD+4f67`0h>Z*-2aFWXnBk5nLmeP5 z3^(f0A#UFL!f5c;ziC_4sJJ5`mi9PUx10OO0%!j~O-q9!LR26U5LB`tj;X*N7=3rN zXhv(|FT4j!Ke}wSox``Ad@$^&`?V|N2iL%>YVNWk{sUlPBNRci9XeC=piyihHC-!x zGCr(iVgS(;AL%iTIG*R-O@FN+i#VB^pvGENfvUG&RDfg7`--*+Z#K?TNjs^v7Rg(4 zyx&7N%gWHVcV&l%d2lDGwDB4Eh?lyXZ*cR+((J`(d!A*_qdgWWKsfdEf$`;U^wOYj zr-rl`B}Q>2I1j(AtW;pCl1qF#;x)4YJ*5zwN+a(AXp4Bo1-}nxt*`2iNQfL+4e_=q z+-Xv);}ZLI_=TA(al?Dp#9OwLDG+RTP# zE1p9n74$EmqCJYIc*etD%gWUO@6%y6b!OhfO0N6UfuxDuZduWrd8oPYPnns@2E}T= z-`i9o8KCx*H}nO;DJHu@XDE4?YGMMMCwfS9T+C+Ab0+rdOdR>Xr8j5y97`T8^Xjw% z^!Xy#f;jQVt{)kzZ`8?RgGm)Dv9!<(!(W!(lXb5MlKz8iQV5#r9J1WgD(qh3Pb%3& z`$`aKp7bO-?zTj%K{j0wRoGEM?2QX4d5Tbj67fxnznKp4iZicByw8q`C=gr1O%%k- z2%r1WCl2Bdz+{?BkJzUIv|Ra==Ck4j_ImaZe1nyCyEJwu(tEICaIhD~^T_*^1!?sa zMoe9tU6el9PIpDmrvE`R)pP&kuZ5kZMznqg?EuKV(^AYGk8AMhNm4U0V_5lf+bV;I zIX=6H`o|>}ddjRde(_+riq>iq%g~-j*GPJjyA$x9-IXBozeR53h5{Mb?a6XK&ObGI zbiRm%6x{TTU1^Ua4MA`)y5<Ony>7eiE8ORcXzjQsjaUB;AAqFa|r$wTd{8=BW`T-J87!U0W2HL-#mTs0*L z45e#S5@U2>5RXP0qg)$^pv_yI&|R{D?#-q(y|@}hKPqb@sQ~ZVQ9f5a^TQcViLs|E zz|;p^8|XjD(y@A3Kk=-~-QpiT8bjZf$D7?7>yQ60-rhVO>ivHo?wn4kB&XAMB2DDv*8lQ1ejkzrHw}@C7dSxETqt{+=%;&2i{mD1-4o3(UEqVS(G^G zM(ke`tM6rd=KI&{0%O*Gd2PA`E&Y>pMmstWx!`+`JW!6ICWBs(jdH?Jo5fO#`O@ld>8=N{l< zk+Ki5GuY}iNDSt_ff9E@W=2KdMX%6-GW3kyOM$;0@U!`@MKH9f{HVs={Z8H`Ntje8X7TAWPboZka;3Ue?hf7C9yw@F1tUh0 z;v%zNBWDNf_aqXrqjTGiMsntE=nb;AbVOX%u)j+Eq;@YTBNpxs>053<1Bo_y8KjH5 z%aXf}AR9|_7dHdL;OFAsG29`10xcjo3eQRvz|9l-SuY_QSESVexj-dCenq=TCU{l!yjYW4jh$&ME6Xd2{~kr zFN9l5hHHb>KQ^JboRV$YPue3cp-k>Uc6bSiT8)0YX|oVT$2u#n-Ys|fJWdqF+YY_C zMt*=nbL8WRWAQgZ?NdEptK6Zzo=se`tVRzQs7HddeNhLiot=fljI!Gx`?e`|?o7Vy`MH*^e8F|(7 zOVS6|rBP56xA`ZK zq?%7nl4Z!nyi~K5YWevT@7~evlTlp=>?>Pj8gLx=eN6LT!X0cK7wmqjGchiRqwi1< zynZ}bAi^OR^H zl&s64pLi|#$!>RX?>WKza#McN?V@-^pIlT70_N}7i2_uiL8(Cs)R3d!;-e`A1y2+g zClDe%k@w&JQhYZg^oL?fbZweQBX;5{pj~m=HVC+V}!Z5>dFg7xZzWbVZ6b|)Ycu&W2+_jbu5yC>mG^RC*VUtVMj zo69Sy;Ce}zV+~V2bsU5=()=c}t^2k_;Ar(5u1H>y3o2KDjKX5-HpamsX+y^)?rJRR zb$Nt6toQ!nK}O4fG85HTF@WlFFQ*jJFJ;HZiD1jaYY%onq{}Z$Bq4*!6{4J! zc9>&}Er|EvO6q(|dwPG|bfmbGg&r!q3nHUk-2nfc(O;)k z2Sz^pseUmL*zm5qc8g2`Jr;7jH+`doRwYH;U0&t!-YI#ju|8%(6eW`0vCFpS87n%1 zBVwO{&4q}JVFc_$S27qwR4_^b(d>KV43?vdKW|b2hfc7(XF=UI2b z_@y4{qYhNsxO>H}Y8*`OW2p-L|R~2<#2&9n$fy z-N8#ZKc_*%t*9OHgy9YW!E9T=5*#-64_CfnD~jn=<63;M;}bm~B~BmZt^vyb*N4$I z>VPU}TFzi&xE{rWZWA$3S~pkrvdr(u&PW8wOVa9R$fED~_nL9#)5+!>`VQ+TjiKJ0 zrqRn{;=zSETAxPR_fzV2Caon*t!}}uZy^@_+ht5<5|Hu7dfLTI=;f5nF7_!;PyEAp zukF$QB8ORN~``~vXWv3kVkohhT4oovP=SSY}&-oiSG^1 zi`)aNwDoG|J1{rikpk1vnd?q{m+Vj%)aDR^mPIG}TG$qySrt8D$i-dPoADK7MmB}-u;`F)N0{@zSGJ&`EGdQ(^A`faWA%hOcFOhWs3 zT!meP4+YWb7vJa5Z*KFoD<%<)cV&+w{}SSWiw8tHt01)NI5T^#!XE9(?>r3C7~Ke6 zb!0fy+s4IZREw%3rPPZ|^8B$`c=PFF1<-e7Bb<;|NI~Qn{A^QUpDSpj)Ug9ct%ejj z%qq$ei}5wV*2xN17Ef)?#*fF&{AzciXNkUUdf*Q zG9h?j+r%ASAJWv7KwpYAe~n2cPMeO9=BhImy{S^U8foL}r@YTkCF1<8K@v<7Q_7Or z1Cl(Lm~dX{n-x|%P2P+7K1IB7Ln?QmTB2O_nyMsoT&sEQ#vBX&8@jBvnWiblUX;%+ z2gZ<~sGl-YGD+A%L=cNg9CYP|q?C9;gYz3Y?Tzg1s_cCf=e~Md z)=M6e%W$w(U>n$<$k+;0ji4&xXDzbWLLz@Ll!^9 z=N=u5!20A1c&0Pa6HVPCqz+%IrQq>~m*S)mdgT(K(D(3nS)LI50fbPnuTY|HWyBzE zV;`_P@5ZhngI8ipR~a`YA*=RIYlloou`PqGN8&dUP!@lPzuS^TF^J_i+DV0y*zqo6|G--^9{MbM9$2NT4TC~0Z>dTJvvpci1imYtdS3&h zL&Lo;Fy^@auNgYfo<`#@aeRLyJfi>s(*lzx z1oXXsZv%m=V(UaRZL*)Y_XVfOuQ%XH-8ac&eEnPyQAeq?&(v){6@wtzrcLUi`nIB^ zcyX3MWmtTdpv@u&i8{u-S9AGvCO$-QJse4`9K!vI0{gX4S>Ay!^B`;qzP9vEZv%RDxwSE*#aY?yXOoNiWAnF(x!aaL z0mI{bF@P+Ve|3P8P@NjtZ_6ENbOf;?3Ts&9x)Y|B13j<8{0ULFyqHUunC%8#mSj%d zk@YD3?>bwzmn*SQi^!tg$)~G>RW+@mmnCu_+-JNqW@u2^DAT&H{pQngf9!&oR}J$S zgb8nXxi_{M4Cwf2KM#DGT~hC=-w2qGzhc*)Q6xB8h8;ml z&3Sy`?(BKsmyJJb|97YB8Lf{ZynKk>G-r)|=@ytGbDmwBLRBVcOi?91x)75MlM8_l zBpv~Sl88zgLp=p&gwUAo0RR#=s0^KY(C32&eq#P+yJX!-4@StJnTuA?QQ6^Hpi>!- zs~BB!JPfcG{g^Le@MBqQw_2Q!lb@qlM<(CbqbIC@*OZGg6@Vm^_qN^BIQ_vVeFeJM zKdlwY%g;sGa&(oF|3Mrq8E9kDuSjc_m)-Vw4_C`<8LbjT-_oT_UE(9doyCmD26%d- z*>U^b)+um|?$j5*SHAF1Md^;IDU*{jg>;8rCv3lGclMyU*8#6P8>#GE$fPO-Y-}^m z6HS&;`Mcf!HNX}_iHJAl?^2ZLef8(Vmv7&zgC1yJzq@eGKaHCOjidKwC?Fm3L#@jk z4Db?%&*b&41%iSH8cg23@ZlqkC*jb1Xk5fCf!~NZYUnWQ>v8w6st!Req>=ib$1<_I zT>axIbV@fjWnpp?sxj)P6oEM1Widby5M9axs5E4ne<>wR(ysjCwUN9UDhFnx%$ODo zfq9Z4*=+$1=8hk0(pT)ogJ6UMHBQHf9{+lMUp&3v&$#hm~HG<=DH+Q&4e6aBChr}|-E_u7G2nG?H?M?685Wl>t)GR?kq zoRC58f~VFA&{@C+m_2aZ>C>@09&PhP^wh7Wj6}Of08&E4zQMtQtSsqjkR&Mt<1fZi zIezjrcmRgEcX&&zE&g?hu|le54c99>4Sf4n19v}RA3WWA z7^Em&I3%|c;&z7d)kNV=68_nt{M%_(i*hSx<$4GMXV>rUMPW+Wo62?T|-W&c~8_4YIZs63dZaeIiB( zR97!zx3P`(EmH=;%d#2%w*};N!rG_&PuNw9g-V`vEjby29x|zzkMDm3ij{(WW3B1~ zSXGrNgN7K$2#AA5&{I?RcCQ_)slrKWG?uT-m($eZu1NQ+PQj>s2#FC_KQJJp7S=)U z(ok80M)hQ#7042u;9Y9PC%6UM?FjF-ZDQ;xRK?Br)M((wD;Z{k`^1)0X!4Yh$zosX z;fL(Z3L(?+@thDD1ImZ7Suijc1oD+ld~(2+YkC+oJvjsIE_ihHx+&i~UY52Op7(Ac zRc@^Q(I`a)sg1K%22rIvXMk9cI4?ayH0*f137+-tajf)*^RyM2S*eQ6)x{_iX9@ol z^<&6l;{L@Pm9L1*h#kwL$|ro|KHh-ZbRxs7XK)f}O`+D~aH+)v%5)!;9S?z&R7XKv zS5u}AdAk|;@BUbR+Zs!DTLGE*#)wpQ>%I@M$vnTjuFG@8lB8!OIhtzaOYOV4me#Tf zQJrRy1F4yTl~I#)VId9u^xr^%UBKUk3ze=7krz!nFo`4L^9b0v6HiTXi{SiJ2pWJy)hdiyv;1Jx6}rpzJ*KrW(7P-|YS5 z?95=b$E9A?M7#B9+h#|l^{Fhgna&5^tjSW-W?LWzaCb6LN=W;M>~+r4Cz)qPS6pzl zPxQFdpWf8p;P`yr&7pi8h^P+!qhVg{O*>`78(jzqwZJ^5y}Xp@I2gCv?-$78&c7T$ z0Av7f$uTF7wC$@xa%jHyaYXu+-o--7PtQai?9PbI7fJB&3M=c}-PjZ!n?rx`JE=q& z1%&vAp9f&HPkij|-V~YXeDrHUG2A}5v3N1ssRMJ!r;J84BX;;ITh%%GhERhhCn*zd zgA}sO?tLxCqryAWnLezE<4LWXT(YnKt40DTp{~oo_~^%Suax$7+QRy?0@WXKepZQC zlaK!nRQR8(L(bS6yYGe^XO@r!%3&`jdFk2EKvlKQh3!zXoW6Mhqt}8#FXs#{jJ`qO zj>Ej7-bogw2c~-&E-ceO)@1Vc5l}B-HsojLS{?C4-gA75!x z33j@#Z*Z7%9Wt}}zoPm(wc;SF!G-CPMTPjGJO&^WE@)p-2t4UgB7(}(z6&*2*{j9A zdgBR#F~)x3e!kf+OD@+44ed`S*J;$i>G-LqKwU|F!(=8|GSQ$O>~(xgLEKw-(;zv_F8jqRtMpU7D>hWv_EBk^-Lu6@|J>| zCSB8aic3WA+p*c?o3Fc>9)ogzRX1-4w_97(Uk)8T4XBhy|Ao;2+dEQ0E%QC#>(6%t z69!Ymix9++>h|+q{S&@AzxU^-^=@IzR2RPEO}IrJDV$j-FaZ701>X##Z+#WdG)qX& z0l~TU0!Bi@`Q!t;U>Kj8A=?x?O#CM{UqaWOGpJ9zSQuRSsT)ijwI(=MATP|oP3e+{EyO#%kqDHJ|S2EpO1YV=M}O# zVv$o5Md`oHqgujtngaRVeOfS<%}t@olZnNZ7RAZQ!2?HkU%wCV#}2}MSE%GZ02_q} z&tv)JCjLbE9UXUn3wdVE$mGr2aprvOrd8(_4`^Ay_Cj?zm^}7kgr=ltsim!FrUs^0 z%tw(}Kj`KE4EylBYV{H$&IZi%)}?+QiCtgg)1Xs&q~Vm&0w6B)w2rh)RkI)!U#jgk=UI{yT6;xz>t&D`B@jG<}>W4 zSUnAbs2VLOE20Y#A@wPP^3^jV1X8-HSKzT-MhTS|tD=J?T_0m1Sq7xYVph}VLWgs;loW((*LSAg@kn1SJOHfYRo?f0R*zZMFMlHT7BSS=6$y=iUb6%N07^Jd}o z9;a`XwHMTo#9OM3&&kqTT*V(imYsBq*VOd;Y0(VA5%XgwpY|_QV~n+pph`VhaU(y< zM81EoQ}N@z{Xm zWNjpX6EnirW~g&REqN9P6u$%G@3r+h^yZa?njZkzV=3K**>5?Qc_CyC(na z-~Z>-=bygp$Lr7x>BL8q#BIQ*R{pq3 zx<2(e?E?Bh90V%A(`u!+H&FUlG1?%8q5>yfFR1P3?S18dj%b&ACl+MGEG#Y-78JB9 z0ratUan^ka-2&Q6R!LajdSG8|Sku|GS6AUD^E<2k<_#h0_%YCe9I}E2(<6dZYNG(< z?(0;?$7BXqH$R)0w>dIA3uKf5FsHiGKHp@I4q(61`7l{xMsmh{ukGKK}t0cVeNBI$?K5 zHMyZgw(Yl5CoL9%cP@;l?+{4QDRvmoBa_CJSJfO~0>W@?inJXY8{=oRc@O0o)4F^6 zg(4KL_z#DFNA*`iYNN_&E?_X6gqE6@7rJ+{5Tf$P#$czE=q3&IauwSd`yeHij3CI% zx)8psvI{h;GB8R*8)l@LouisOXOW^Z!nT|fsRWcHxpO$tB!VZk>f{~yqiUpI!;>3S zphA{B^;F6A_oU?J5^^>UUsB0BtyGl;)B^@N6QaoVRSCtKN#DD{lb0?3>IOH|P9wbX z&eJtwj(#V6%8u;RL5fj9PtijHroLQY>bnkceCcmzR8RE#Y`8~n3Hrw*Y*M8iCgrPP zhNlnUeH`h%_mk~-M|R(>$`i^iC`02sA?a?CfiP*4L>o({qF;Iz0y{+ssJb`dn4kJFKdoTss)UmU`-Q~oZT%ng zNXVaeDB>J^ap;#W=uBgoSecW%qJKr+8t{$OUbP6~CPh%sK~kT!$nq;YByA-=;&fIlVAvCHm<6wny=jS?NxTW`x-e?!ChCNeW_h-Rcd29V7#QC1LX?*=(?!9B!6PP z?4`fT?AO1kk%2jo9x=a>up7U+R>h^YzDx@D!Ao+&at5R#|D9Vs|3r8#zf1{#$T|o8 zg8W>>d}s&1c$SCcAin#B`i0;AXV|!Lt-gORSnK|4gu?%CN?uFwr0Pf&A0O=XI0FXL zN=}l4Z7;oN%=;hy}OK%{6_57h>ne`)7~mw5}2bO`o%nGdLt~`+nm&XxT|ivQdq67!)A8}wS7v~sKpL` z_&D$qJtJ@0P#{I>if&I|)C_52^g$OpeFV$>pO}ijI6(8U#}BVCj-XZl^$xwjIWTB9 zt4}UTPq&NeiomoY9XrR()fV;zC5KU#J2q*^t%}K%U4j~x`Y`|wUG|c8sepUg9Djj(-Tw zR1xejBn-bGPB&CDH@c@UAQoX#`}SFViq?}S=<)W=^|i&yWiBw8=glk3|DnXQ^ihh; z9}vd5+s_^}u8hQ7lz&*g{%s@zg&umRN7_aHLjEj*s^!wkkmeyx+6(BjQ2d!VwDp-x z43DzoP!~ac$~~yi%8FPsS~9rptakK&0GPmwAU@Qx|Hoomaa1#{0Cpcg&>$efTfW-H zvsj4S?v-=Gm8hj7Gz**H(Xxcq#P87j(tvi@>Vi7gX@XzAW>tI}ZQFUYwibN~ z$y=7i*p5^AuY5e8=Rc>|x7yl`c~|F6>|zG*F}CvRe$L6nrktW2?}3)PR~DaLO|0@r ziip_e&QDG}`LSDwpKUG(SFc(QU4k*gH!3~TTnZO>YjKQ7nljU^U3Ij~ACDp9JvycD z7%``EmCVm3lcxHmJb}$a`KKAN*&YRV{_pNh6{q6~2gAo@(}kbL=A!Vgf;`K?-c|QY zWV0i+;8hO&iVnHF9cPqb4V(K>8M#QaSLv$qVz+hL>tpIzJjOLUXJMIHw|lSfdbr{h z9Qw0R+ly_Tb@AW;uBEA@&zt%e_G3W`2K{gM#%^ulPh;@(sggksb$gy8ur_hMc82Ac zQ@gmD1?XW{mCY#Z^PZszF63`H|$rk!xXVB@1CBfKc6k_Ts-y9Dh1A1 zgM*5sAf3l>DuQHR+7R|zN4YINBL|(GW@S*>FdF$L@^*LwfDBj<52I`xUtJj60~2)> zRDlciHgA6p`lJM^vf*sZ+{z7U$fAF^f3=rQ#DS~uZW|v13c~zRBfK4T`02a{QgYii zO_qv2Nr#9m?*B!yM?$z)&4u8}QloSbPGN{e-iLC#PPnI+)FhuBfLuRR$sq6a(QeC0 z+NQlqgp+*o(&w8btA)fHzZi}mRgb!G? zqMG`La4xqhOydSc3YNDmb8nZt_aaGV=%5HKP6psV=?k!`T!s18vZBYYV`-vj% ztz78#G0TPy+exs=-VcBUiJ?QkHB>|)w~Hb`4F10+Xg@>2naIWYo5`BIudjOBa?q6x z=Nw{MB(&^`UGMLr6>sfQ^Qi4}46{tx7$-v79+Hp<=7`|H32;$G_pDv{rJct>Bx$p; zzo_z;pksLln>^2JBhoCtkdI-CPVpMs$GI2Xm+} zeqkZz9Ri=WRjE%w7Q9eVjO0Nw!k&<%m=>htZ-MF&gGwB8@RR`%q`O@S$AEDLei~PL z8NCTrSi6R$uiUtUvj+zoMgo8v{t{13Ke-9DL&J9bf^unZPZQAoaHd`KADS+6&J+Ct zS6!_;Xl%!OsdYH0zF5Tp+wZgI-q^e#$%Jm~lfL&_I0q@EQ={91XEiAkN5F|2+$a+e zJ0MWY4q?9@7xef4=gqwee7{;ijhMeOH+Zmk~3U)K45l!b5 zSGWb_$~{kg-s=i3BOikC*Wfw9G=E7C#iW&hGCg;U!(7sE#nUeoXyfU`yX>P1xm$KX zwBAA~<>?4BcwRwPxZOyEXPhZ@evfvneL?V49yltka_LbPpJq({T{0f5oSi?fUf{Rx z(fTC$x?kuT;mApm#_d%igyh49uic!o?Pg(u9QtDouWV99y11vuyL9Q*^HH?w^)u(@ zwMi6*O# zhq-?cu>Flu>p-qnm^jK;s<*B{q5pyE&4pysM$1yO^1QsuAh^I@qjK&j>X{m3UjRZx zAFaOGV?YA6Zry$v;f@-CC)es5J4RYZ@m*A%GZ&#yc50>l`mK%JrxCWz)D#8Mdt#pSi)&&I%>)vc|LlhOMwQ!kmuMaeIWcKOvV@}O zXB%gfjYKa|4H^-PLu9jt;CY)V1lLJQ? z_)x3vL!2Gg%T4WnXYw9zs2hF+-t_mIDjf9yRRejdyFdkm7XX`!lwCoABkzo@NZiC$ zRAa}&>i-5vYB9UVn8{w^o|BmlC*d3Lx=JTHT8g8D@Mq-2JLaof2 z7ZSo(ww?^Nz(pmh_!G|VGJ9Q_t5S2a*)sblCJzCdDYn!MnHnl^>eVbXz)q14hYw&t z)&)_-Uc1;@JZy$WFC4rBva=gE=pM_rnaynAM1u|bvDd$D?=Fy-gs1?AWKiP_hVnSw zTJ||o?2`&3#lT6J;riTq(I*k^gDtYu%!<&!YF^n|9Zn+=e)p{}$O^OCrD=MYnWHg1 zFKE&aCy~SHdtW;iV`<8p>Pj{$z_HBe!Y z0EA32-05IT$ek2P+N3mtPdM^N^-q2TJ1JG%muH{G3+*=`i3?#fKrTB|gjk9NxgaI! z2eX)>jvi!zLex7FVB8*s4WRK`mxGP2{jN~ajXtGF6Q7F^%P&b_FREi zToYbGq>txdHJ9-+k5oergC|nQf@o%x42AB&)Wc$6r=CUmoTEY%>+|6CxPzT#*X9KRUVK)k;mu82`B_7fAgq2vcmP<}Y;+i5fZ8ax3f)23b^*=R84@-+5t(Ut)fEd!aP z{iR*py>Yxx6t&sBQ12fAmNtk0lQtmpeyWfd@-1ap21NoD`E~v9xX(w=oS8C*YuO-I zNie_i4uSplMAharImof4B}&7NsI?c8GqtKs5m;yM%LrN$ti~*K5P~YZr|(oyR~w3b z+ZI#)9U0gM9spCZ5EucSC-_o0Wl>y&Hg_s(ScNMeBALv|Jk|*ykCq7N$QLnPzY_X z&gjext$D2bacU{2*xaR4N86MgJeez_xXd$fSSXMgatBcb=!H~xD%BnGPpFm?oL5l; zp8X;_2;Ud%(x!kJ3h{4$e}Z}z77d4Fa0?#UEq5<^_j7XLR(uC)k0CsP&W%sx6|ODR zvMHg>qeKs-wv)KukIGH6%HS;O6yGZ9(Se`Mj7MMx0PG^3KKT?DPn}cW*F2Sx>w&a4 z?R;6*cb6rk&3FIZwP`%jCOjq2_i)L-*yd@k=X*yLM|mBz+i@sF*JgTS_;%&%i!s`2 z$f(g>ywLdg-n;Z0GPp-uZA5g)Pf^C+)WdeDz<1e9BJWiiHvE7Dx<%X#PS{N5C~op@ zttU;*$%1SH7>@RuK>V{R zY_zp&^4G|@QRWpvv~m2v2mdopehIJ-OIIScVIo4V&l$EUZ(qCKUxb(2RF8BgVnHwH zj%j@2%!lNgR);M~`*NVhZdD5`NH4I>I#t$c%f80`uxpIExZHFjf8cXwH?mp5W5i3d zF5fX*Y}jAFtti)l8TrimX$NvFfxU0AP|3X5U!tl|QwC!mWZPKBt7>uzJU`I;S{t~A zT4n=6CLfPfJKB8M*OTmArRE-0Ad_5}@4w7(p46%#Xl|rA6&&{Qs5={x;IK7*nPJ5% z$2`~_?3w>q^X-({|m z!R)KsQ*|V@dTlkV127z9jRJ=pqr@qHD%sKpp&qTUNuhJAKFMW&+Ln#frP9dHv3_os zM$qn!oXo`&TGa^JUWYUTa@leyNz=Cw5XXz+1*|4~Ub z$r}8dJuA-OzN~+^EP+;LG&+-WAo%$YFtZ$JuMC3oJZhO`?T9$Z2ows{+(6-7H5%z% zHCt^5q>$OoTK;^zoyJCa-;@FkNQL4xuylrvJ&Ha+0-f#L+kTHz{jB59IR+)neFo%D<}hVuq&q~>mGAmJD<-&I%o{Ebrm4QF5_JoL8BQjfXH0DjwiumF z%r&2U+(6lJS3L5WQpdsY*Nv^{<#9nlFF0+3gAKsfyn#01!>dVeU$YKqRBB03=3x*YHN%XYm>$ryjPVDLJreH+NP*tb7 z4}Lk|VO<70ma75sqi!7p;Zg17KH*qAdD>VgzvaN{!RcC0uaCI*uIGg|}Nc51CN6*dVgH?$7 zkVZx9615LMrCmLT=T`WH1QF);S$39#T$L8k(}MqAcpvq~YeZU*IzY~U^y##%HaqC( zBOK}d6`x&E)=33%1<@ePhba!_X?e7gZ3w&g`d&|sJ9aUD%?gsdHb0?DWoqJ~l$40v z3P3uRLpLa!5P=|C=uTT?EVMox9{Mdgz6>+#_U!1|d#@-0+zb80$D7H?YKL1o{J=|p zft{7@Kw&G*T3RMa<(G$mWg15#C*Q^HkO(5*J>x|hHJ#jB2n5J2w{N!Fy9KWTsB`~7 zglpF!-FvCO>XhaK42F_V^2=|@LA%*#d{{XmyXy7H)%8lD@U~=z`JjMimD_JY?3JW~ zW-sBANtLmA#Xpkb!Y4UUl4SDnTlKn=z<@Uz0pL;{vx7$w9cJRY_CjlUX0}ArZIp#4 zX&nFv*RCQDquOX*U0r=Wc6q@Q2uZd3e_8#UyPtx$^|DV8$4!9HVTYFf6!_uOPT7t- z@|~gr{OI60HxneL7y`DQu&qAt#TQ*n+4cgH$xPMdpi1=8GsGe>#+2Jt=ipz!1Eh|| zsWk<-{jbI#r|vSyA$cz1EWsM-$`p}EN6WK%6AymQs1f1YYh@8yIa7#4`17AHV*2=1 z1pc4>(mIikcjtqoh6?QJ8@qG>@LFkgJ8`#!Sy~a0o6Z_c1DZ|Uh@LzbsTyI-FDWc*|Y*ipLGi}O3f5{>wysd)-1^6EDJ2ABFY-ez1I6j=` z4D%i-VT_``*$nbt2Qrph#n9hEcXL$9x#Hk}*4A>%c$o!{ey5XC+T3cw^t%gHp+9MJ ziH*}2XwjYL;axDV2$nkTX=q-PtSs8==1fcnZDlCLK}OBnntZe(JMrV>%P#kClh2|P z6P&&tr0tDLY{8heUKq?ypsj~|bu@Fc<9BMBiG?r7P=+Z^>iu}0b|1HUv+fh}&`_%C z2@)+X1~jN3PuB>j;WNzv_%x1N_Wp_fWJ6YAL@8h}p57)*$RRNU7oJuRZPjyELrV3f zYEwvlQ@7RHSue3f7{=O?iwT)7I+|QIe@hhQZpKyxF*tH9og#HnRkmN3_3J)e*kz5^ zcsdpzuc7nFtm^~dl_vW$R{FN@yf=ct3JTjVMuvStxJ1 zKYQX+cnHlD_LHoBH;m8})+~{^v=q?j_bV(QxLG1N9K-Zpv9Uh3*FwyWd#@M|n$qho|l(=4N<%ipqs-O3Bxt&@LW1f;_W&EHyUC&DK~B{ReLoKgDM&sCa|I*9IPm*e}i zX!oWW&d3yTm|S9YnAxze{LVKfWJ9)dfZ=hqZ?Y*EmqHayO2`M5hafoe+N(+gNj+b# zz)8J3ow(N*`LIISUY_=7dA2;-uqEp4sjNh0ip1^*`FicN^<7nkn;FA_ay+YFsuKyn zNA9zw1i7quKl>1NoAA8wCFPA^$PXNEy6oHMGqiLblf9J5j(#(yaq=vb#w^FFoI3S5 z!>w|)IlgkkWi%Grxp;kW80hh;=t^dokef!D)jyL|)qX;MU|rSG34!gBvxU!y<6Fr%zq4@?2oj_*4lYfjUQ}e-gD3*Pn_qc&Y>7U5d z)NIz|b^pfD%sBZF0UIuRHuA4C}mn(nI4 z*lW^``hFpo1=45XbNdPyi}cn-{>r^drth3;<5(wKWgmZNQ}&=1rgp?xF!^CbXC>2= zzoJpjR@XmuMl2=Xj>yIH=R%r|)7SbO(G5amDu)z%mGGOWu3pMi?6t>!`(2qWSBsJ) zZ$8_gR(pd|em^CiZ-gRTitfG|9ufo*ZDqDz4m3Qqkz*efgb>rw_bY{#>9h(Z&f93a^`vVHcL%`P7 z7>hNP+ohEk2My`O{qBzQ$BfvP=JRA`hDk26M?HBLq!NjlTE0GEqYmios=6rU69b}p zt|OI+YAzbwZ{zd63X>zDAweSU@qvM?na zWl^@YO{E}1#^x{wYoF5XXe!D#NQlUlDWG&Cr&9Lr0}@n;Z8;V%Eg_j&xQL2sII58m z*T1v6=RW`4X>wiRm_KFPqRMYazZ3~V=an|-xgAD!mWzw>qz@xABQMaF-UZ-uR9lW+ z-@4d+9kfU)q40o<@v7Iz-Q_Bjh~L5;Qo5xE`Qf4l6?c(h+1VAe$ww^BG;scb#}Hxt zqDaunm;ncVdN{a=6G86At2fAu%*H`4yWgzbfWWDR0uX=EJ4ck*DGUj-Ft9oiiAuD{Co_{>?Tv?>OHRL;`)VV&8m@GAUYWs`KIHoHopi0Q%tdQ%*88Xf z)E9Wi#o(jmno%ej%|4lnRZ%o6rid87X*OWKhF!@`;lax~K81wm+LvBe7F3JaEFEw$ zfLrEdZ-9eQacMQo70iv*p$f$BljC1T{S<4>L^CZ?j3=8`;2o2{p*eq0nNE5-6SU(8 z1g^Bg{T+=C*B1M<&vh+nQpOw=vUZ2k%XMzHQpZBzLo<^>sx^c8zT{TP6U9*<++mrk znEY)txSl2;9B#Bhuy9U75W~niCwDKp)HKtQn z&#A9Z{j&Z>Fmzd9tM*>SI#I2b;WIMyWI|i)cHECSigBL`0T?fgJ4x~~1Af%YTGbIj zZ;x|16mj^Aqbol@d85zQPdc%jDh<6My?@MqqA+MwpXN<_HrB!Vn2-21rK-CpaL&Vk zIXn(BY}nlgX2QgcHLLvYC4JrdP5jJxaV@EwIHL{XVdvF4!A?lic@s1~=BWkp2xNv5 zkMdrg>(tm0Idr0_<*2MiJ)C69%Svp#)c0X&D>Lxjl6M9Zf^C;}n2uJ95h(#LkfiO> z0iT-{hqgrJk2-fQB96vM2FS~tcNH()VsOjt@yi%U4%ZqVwe6wIr-}BV=IunaA^#zc zrV}3ha<*R_I+2=-Vp8iT6RgC#ogWEnme8_PAq^djyZh0-?!a?GPEwa!;( zK1UQE-^Bh+Lon)O`CP=}MhuByU0Szm8xjM~!CA#iYtJ`G7Iy-t-AXmCeBGI=dsY2X z%7j|>q5nhpFpC0dpxlcjVp1deVyng5c+(uSlv4 z-?8R3o;kGqe=@-T!@U0A`Ytv>>({<_S?c_6Z{A3MWA0Aq$y!gwMgE!n>e}K@@cvuO zkAHApEK#SL#lrmN)-&L0bhFjo=QZ#-t{&p>3q+gi5sB9%Msb4+=)}pf4m)pL9eZ}9 zBwvLU+AoVi-^4xXVDm3lRH)pG!#S3}A5qRTl*{x?(c!p4iVd5}CYObB7Y0 z&NOK$k5kVS`H%Lh)9~8vD<@wkM455~pzw+KaYQbg^Nxet5{evL^w*Cmk7D$` zn+fqd(<;e1@~yo#d>eig@y*`$bl?I@fbWggalaG}SDfr`XdD8rtL|uwuf{`=1Z;qH zGs`9KZr{B6Nu-76Mt}rsVwr4-Hp9B{ewwp&5dJb(miKkVXhQ2$s@r2rBT*n(QAd=n z*XEz;>OQ?kEdZ@`m zXtSvB-x|xVH!JpW)iY=zzvUJi@}vUB@6r3JBmqPgoeFsk!X0C>yHnHs@o9-sZV_GY zxTsZ7`@&nOhA)bPx?~E!-h~ghhEsx`Q0ps0KhH+PW-GTBQHT{^ogMrIX+-#y^q`M1 z8yS^7#hQ}i4!1JAn#SnOhNVC7?b8&~|xWhg*zI#EUOm=YIgwcb1Vw1OL>Gm9K+wLZar zTfN<{&@Z3!q6>NDL&RxKrJb8Z<{oIkFy|M2@@ z>9KZ=vJ)NM>FR^C88N*0u9ds%6kEf#h*m8wQ=W)lTi;oQc@y&bRRA|pE#71)x+MRr zR1i)lCRnncoc2}o&|t{>C3e)$i8C?%DesrsVb6ZN=zIV>=0905_>iGe9{{Qwe{(Z! z;7Lt|Svs7=JXeil^VB1>mNHohtrG1$?&;Yp)QlO@4E~7o+PNLH`{yHXTIdTNPvx1uyChm-ScveR%U;UPzf;TeCa;3QsT9> z%8a7Q;)b7%`?NRr4p<&n4hqMzK)Ixkdtn-EZ{3yIw@b|_>q6AF6gYm6{h70WAwt$VTYs`;d3U5phH@jjwQ(fwXl=CN=jG!c)GJ5U z^CySqBKK5_jEqsxzT}cGtvmQj4H&q4SDT+%JkRin9M{%V(D*a|!mE*Vk=ba{Hkwi`u1`G8 zKOR_VA`rzlo!XGKEB@P6KZ0G5;7_FOlDC&?JLCo>cZL)LK0FTPD^&B@IUmC%!wP49 zR~E&bt!j|`+4bf3O2s$%Ku?M0m#=r#y(qc-BRzy|SoHm?ma?WlM0gVh+Z2;j<1OFd z;Qji6dDXD+cg^Iz&6zF_Zoey@$u4LPWyO|RoY7bQkzr!r7uE6VaMXmNWBgf6Jq)yf zHya&)BD`!|p!nyuCD8r%bQ{x^+t7vgeL!ca^@AUSc*OBH#PuIvT5ey&-WlS)Ypa1S zWY>tkh)rF#i0TLtye}oyM&q3e_hkxuqb{1u(M-+1#1~{Dj@hgQ(%;Q>#(^bM2;5Ojard=@S z@Dln%f7o_TO!78|c&fK8-B-S)-aW-<_YKDlM47b; zl?y|epqc$j=0&Pn^BXGJoc4!dyY+<+CD;5m6Fe+xE>tL(Dgj|Jkq^}#)h=(rb9mlJPNo_iQQFqVXsnZ6-hh*|cxD4Tzh z_5M3`N}N><{p;O1_LeooqgZ=+O>p8&@>dL#{k<2Cg;IF28gljC%_CI>ukD4W-fry7 z!Iugq=f8oFI;V3cJ4eqzXlHgnB7j4&9_$2kkPPl(M*wpLbgYN&Hh4}me69L$Uz@XE z4RIjdMAUHkTX_~ln`?#8nvg)3_7T;aR=>B{(Jk7S7_ z6UB{CIs4$ADs+lE@<5@cIgmIsEc|KQH+*b1xE=0gw$JX*v+2srsc&?TzBwAG9(Rxfgyno%H)-R2vBT+9qp*IPD4X%zy(yDa1wg0F1?S$cI+sKbdAC7)(5vyx z;P(kUz)2KerHZ&FxU?FR;0dfb^)=8~-TwZNcMZLd%p4Zn4!v}PwvTOHJKJC$j^p+r z(%f+B;fecCfU?pf)Fh=hB?%s&u_s5Q_2TV3=%85jxikc`J@ae)A<3*+KSSE*G;a;m zfQ7lrQkYLJey+IYorU0+hrhCWqc9NWwoCP4L&NDo=%Kwa(zd3TKf3<*D6mrcLw zi+??G-cQ0PUcH__um5^moa#!B`remN`spjH#if!Hn6nWuxQ7h@F>E+c8T) zx5i8FFDb}}pKZ8#=a#y`S@_cZv+2X2-kJonjO~zQ zHyh2}FYJ3cv9h|*$ZGP#?+v}|J^xkA83lCxcJcEPyLMc_#|T2tg{XKwD)LX_y@;8W zyP-8xKy`iV(dj>aw)iHT!WBBSF#!JFFKXZ2RR7Ca{x7>M z)+<*pf8yjZ+m%f&`HQUNaaxZH7XW7}8C(PGwt=SLTLVBdaW|Q|X&nlih{WApups&4 z&W0y$KMRZmL0D(w5BzDePx>7wjsE3@2q#|aZN(X4MTT(bz`}0efqRvY z>3V9}@bWBKGx-n(=O>v%3ci8tXT*F;5w#X*mWBK{+nWNU-hRv8q8k8DZhrI@@rz~8 zm+F?;kr-RiwCbsNx8aT5hl{o|LBo;=Nwq9HdFSv}UEO~Ly!e;zqJc7!|> z4bZB0{>o+lgI3!9H$M{?f!zOhwHp6nQ3z00paNX_P*># zMom|vZD+Rt~%L9%K>)xT!#&B5;NwyUx}C02VitH)+nzV(YnS{3`( zE{^%LeyI?DM><0>nwxUJwixVMXM6NQhp#EiOGDn1#Lm1(h3g$A|1q9=dALw^$xvQz zaU#&In{%I(e6!N@xuGBRL;bjiU$A_fQzCkuH2bva5Tu2bhhEDVbO{#6?2pB}G*2$n zPS-TxutnG?YcGxJnd+54tBs#^6r5{OZh3PDds4jh9fTEXb-31PaFax9DiIo5GGU$2z`#V z^Fa=E2AzoT6bJ!DJ8x@z)jWFXvC<1!o5eempWBuJ;Aj_chwsG_yUIfzAwT(#KN-G| z6f$}Pwm0zlhfha>cML9N!UL8&$7UUu`GM@ku?J&gZ^6@s=D@v!Kwr~#qZ>2B#(UA_ zD)wiv)hE%%xEBiB_8Ht%5A>dm272_33J*SR)NR()tJOUy>YtX)Sg6)-yDn6oumU#3 zz}H&>!aVHh;@ca+Q;}B}>OOpUf`PFYm7fLxjk>Gy1nHXg@c<2BQvoyt`RJf@ki~zE zWt<*F zZ+*Jx@=JuhD=32?)qXKkTwpboba#5^U)tyzgK+{F%F3u&2!CgPtFpm;Rz)7*&CqFqQU$iACk{AJ z#q!(Hrymq<9WH=AlQl;K4%bnWeV!^#DX@bbU#FI=l2h|G%JhP%6tKoZz4cIB5z;%Iqwbl!J2YG^mqFeAN?t1hRH>2h zVns53L~VFqtvuC!+$WKrb#l1f)u*oI55KDn;O>d3&b9TeY2h%5_B-tFUMJ@R{^`KB z&#}$GN}=(aFM@Q$qDI5u=M@W-PE5|-@k>+9K7STxU4J_X^Vj%``>%=tz>kW3*QRYvHfLVue|c?fWqws zOVM%8i;ay>^;N7(zf4i}QTn-DIV$z0My})CKkj~WIrHgpn{R$}HZ=(QzJFIp@^{Tn z+)0i(bA}aB%f=pfc?$G_8-P`!MG(y`*inMch@|1uC=ExaT;QzB$qhaS??WB8lEsSe z_&TCf$Mzy+@x|Ztk3-G}q&foITkc6gF8c7v^IP@r!!}ls?80YTRW7%VAki0X9k#li z8RR%Zo|hlnA`A;J$sXU-26lII+xz|Z-)C#@l>5y>_Pu)Y*2CrOlmGS8|ILH>=f~S) z!0u+M-rjicx`Y<2PWSI4cf+s=W8v>#-BMmsZP}%mmDMvmd^!7l_5l?ORf==}QN(?6 z-qmZ`ux)YybxloIB#kwcU*+!Lk+PXHEeB(7|9Ib|wEes7_j~6yybWJgsb%0lj@(;w z@aL8tP%}T|ezy6%2U@k|GRP&hwai;@Gk3mZz;-9Tw9Njg`8K)uws>y9z`#IcZsh{g zK+Al)+{=Bk31>`dL7eGjt5`kEQzw-yEcL7AOMa+At)7&`E$2xCWwkw));%|Ml@DZ6$q_=1x?@FK<__EQtXtO_b-Kqs-qxeexY?vPmb#|r zOvb8r_4tdtx9gr`y%5W9@Av7`?p>`Lr>}EnW0zk^mZHvo-%$tFzQ3zEnOkIksyb!$ zfHqe?+{$wRGHiqBVtDCwkTTRy0Mv_xO-fh<)H~RAGh@=DX^ikIv|(`&$ zj!n-klln%t+C?+93a~As9*{3h7r4jB;1^9vS6+N6=ei|2qQR)Pm;iBWhuMq0SqlQ& zVhLhLm-r~>DQh&r6@IYtqEXGENgU3*z{HMVPw@ywUdqUv3&y=dS{sRw)PldhvzvSd19`?f zv<1EY^DHn9l!?Mie%s#mZ zt1YQulZVdIpk9J?ah+v}kHRe#&{>5HXj>Tj^j4DT#M}Dsb28C=$Z1Qa|G%at+}$&X zAdyxQU{pTA%-Qowf@gx{dm~d`z&0#@; zF-D}0ul=MAsM!gBKo`CGacfP2;AlR5N1uUE)a>fK|2{=)q;KcZREj;s zZ&2f`HiV@pFBL!o-#58h5Qo$Maz=S={p& z*YsU8$2a_B2r`OTH2(}-QrfE6Rz6TEP zPevjMeseZa*P+)Gy?E+;}zA5O5EU@{7PtJDhRB6)n=iZFz)4xSLZE#7tdy{Obp z7sB>5pRRK|Zy3Uy!=y3F1{SSm+^=c#34)d@*VvmEKP2>$8JF64VLqqi-nH8SX64Rj zTN)$?)fRbbsBs6e$>V&W#>P-@USLC5d^Bj>@!NQz*UU%b{wRI=3!gMYl?F;ZqmSv@ zF~68G`M9*zLD_%m#!tQ#6=h~}(PfMvRTS73e&`m~SY>1q6yNCLSUy;fK?ayi@xXB( zmVY$T)c{VJ>2b&xcTR7~`igus>!ka&7R;zZ+4|Kb9rYTvMvS5|61RJ2t1KX(#U5Ir(o{a;Oq zuXcoKhs^Ica?cE8k|Gto^=!T8FF1shTkm`xSY5vA9E#6tAZ59uL7VGRLfDb%l?Kkj z54$E~t>wdlC3cdCDAO2(!~&s{_0awWXI&b3>5n0jwB34a1rNxPi+>j*^>i!pxIcT@ zaXE<>8P-tN@$-N+SwCz(GR`WVpMhRGYeC{(BKDGNy0o11;+vq?!#Q5hi|jFWBc23i zn4Zb*!_)!eh2EnBMl zA@dZMlGbe68x39Uv{hpFz<>~QORW`bPHH<2Hlzg=1$Q_=nv}^(kP?s@Jhj)zqMkc8 zkRXZR|MIOW;{pU2eylN|+J1c?a|6a4(V&!oFQ)BHY$cnR8Yha=NIa;9`w@(DZIgGF zyM9!rjkd&Lzy3A!i95h%FFg16U1LRN9|9g_@Q*Wa$Qk&2Lh=Ss2Kf0<$c%qeI8fUB zdAVhd%*zPD-`@rt74cF7(JL;lHQ_IEujp1VC#0+nS}0QZttjYh5k0cw}f1?ZbpLl$~zB@W8Lf@C!sin4LLz^kiQ0aUCjOo?xE$?Rf z3R(xJq-)N1>sVh2KlN@T;S|@)j6Vl9yF_c*B&gwQmvTl`LkdQr6_!`y3a~ zX2u31E2f8&jEMbKEr8A|&R7kSrdQ+%!!^;{$~X?n;FAg*&q z<+HA@0uNeufJd?GAwlRX%Np#aXJG0HU>G5FUwr+s%bGmS>P*qKP|i{_?@8)_DpB9`#s>=__SnZ{ZD=H)%P3ntJp@> z$@R4|D`-#`dJvAjBxR1qcWj7*+HZj8rY^{`Es6+bASKW!2a_&Rn>N%$zc_G zbeaj;@_PINJ3z>QD1ni(dy!8<(=jycvC+W2(EPL?njRDB`Dn7hOwD2?&XyeN#nVL) zvpyy=-nQ$-G)$xd!~4yAOP#Q+$*qq!Ph*}~`|ryIyq?ar8`n}nE~t2Y^CXF`cN6vN ze3G~&VS@J;QzQ{jeCA z30jCB5SG2|)#E_tLT|QW-BwC7y1F-Xmj;#50&(rq8YS zd?4_Anr_lQP?E&2Yi8lQTEafu3ldr$t_?OVCGgHBE&TaRrBqB{<7*N;WxF`)@|KL% zh7i6y8EQeqsW2 z2!td}9ktN$^u#)lH#C8(+H=tb36pC|r;t9Hgee>D1qi*iqY>qJGML!frQ5?{@Z!VP z=n3wlEo%1pMlS=Xm1t!T>V0bGW^8>&-&n*dmg(t&JMPRMsiY++*Dg&#+!UHvt(i&? z?5`gAy|M*X*;?R0YgxEVu2k`F-iDmq|2_Wo?}cx!s@Vg~nq{fGg6ag}1t$rJuq|vo zmtakvR_lIB@yzNXSu^hBPp`gyN}+ST;RL+vhqbzD#Jv75!ThtUub0rR?_=4R^-K(K*zOv`p)iIolOvY`Y8lO<3X@ zufGH$w~Scm2`uluXxWtQU?H_WN+0fq*7Z?4b{X>H5?U}D3BrpuoemxNS>yHSr9ZQR z;$iH^p7;e=+U~@M!K)#8iJvaAlL=uFvIq!-ej4FeH6DO=}NnMvG$ogN(|_d|Ho!qC1*6~(TXDmW3SJz z!9$ZhveXe~$F`fv3<){=Gh03<5^TP1*AdaukSkg*Nih!paPium$VAlg#+vB74eq3a zvX}!*I-69xrdwRC{)b`0>jC)}&2tx%ZqitK0v==T*3;T~`d#%L2I~lY;wZoVcXy6> zQ~dZCfu=j^;3;Sc?S9G!QEzvTICIn*nXAGNb#ISSezFx+8}p)15mTDIglTgH1bn>! zmuRfyk@T(fu*yCco2sZkuX&6zI7G*!_LZyU&AK)4F_l`FZoMsd_sU60m;9gG5sf@T z+cctMzuNO}`7@b4Yj&zozpiMuk=X(!;Vb^KGolxo++XHL8YyM)mN4Q}?m#}fWZdis zeVO3NovE?jPs==8t-iS%_8o$0{#F=$sByQpAkwtynvZErF1j!NAZOU|B(@3D;eTkM zVRgJN7Wyo~9U;!nY!v?tMKHP=g1O^Q>z`jDL0KgopDqz?J5H+Xub`!-ta1I781W&j z#+lF_Q?^Q~(dZ|m-T1zsjox4(B%v_FX=hQo`mzdS?hfOB)BSa-ondFvKo`V;<4`Yomnxqcy{r6)%9nIk>akT{f!`EPyJq8SvZzwTWEhu zI>$kbYZg&lOQsEAf(kYUUt)HmM0{k4c{(BdCY>kzfK^DPeeKFCSe}|^WIw(OY7mG- z)#IY7wqRjGzGgg3N7DsyFZ>hm=dD`#>e1ay#J$W_PU7XHD^={f$vX5q zjwf@Py!pI|87B9t@~N3AglEsDhym4vhANw$aIlNWK_sh6MFl|;pcL`9J+jz(KQ9+O zxqr?+v%A|Aq1dIG@Pp-%*%W)-rq0bPonuGxbb+j$f?us>=BR5C%wo5n=bujG5srM| zqt44}@wzn?Y_z9)y7%P%zMM(<@et3fG)m}xOA*y{e<)TG{Tz9%znoS$#AMs|zF%0n zw{UE#*{*jvp}d*?;l0se*FRG+Es0_;H=^am9H^!Ttlh1-snIU9yDrWD^!OYHY^GA0 zxqeLd(5$rMYW{}VETZ^U7F_MdxX{s4d;91KTjeybM(E`JPe%O=yIMqg3`m>FN#gaG zXa~_&+nb^k5}Sj|Y0);d3o|Rp>cRa+0qv&LP3Up?pDX=oPz|Vn z(ae!f+}732o_(OsOcf+%YdcFktkKi!Letd?yi!()_#y-UE zA2o5eLtg8wt`E+sy$s=Uz%M)lTN}PkZ$8?eIO>s^B*Nf%1N=cp8?}%`olz)y4WzQs z{$wVZ!8}E44(-_EpPM8)0_}-E=v?C*RiucsuECpzc0f9bqfGC^v#gm1`||iM3a;FO zKB9q3Zl#;W$Ma+41i}sVdRyedFMNgA00(*e%X<0Yay!d$jyTOJR0+^1AHsX`T540d$yX&HPxP6N5K!C zA6+Wmb{>Osf?$32qbE0ySX3$>&rLi?yZjw;WOvVp?RoT+dfn-`@3WgAc$QkXvu8C| z4b~MNJQg!OA0LWODB@16i0|_~JCiuNJJNw@0=O}O3u$T)hTsfp`=e_*E848!kz?cU z*B-Rwdd(_$0{lwYqyAX`q~+y2pA%3-p8V!jWI&*KIF^sE2#rxRS?0S@+G0BPPm}DX z+v+=x#~sYS?>vq*sa_;1fCjUkCwi|{$BOO}R?qv@=Ju7cC*Y`88if8DhAX9&N(ztB zqOp`bX;2)GR=QyE@`GhX`3*}@Uq1Rka|B2Uwm&kcD+reG>!iyN2p7@M4_}R-h)~!~ zh5AI}>|lOhENfX|Zml=t>WIj^H6#$!uwWh)lvu&Q;a!pOc*E+CGltdvTqrDRu~|CR zW+A_y5KQ5!2I!vUZ!E8BOxM!&hv|IVk9Eg0cw2sUiThkGnk6 zN)#oj#!J}DvW{jsxm$<->Kb7-=3>oD)})ts$oi<`cRV};a#nP4fu23f0)k$N9g-+N zY+%LKU1gDM#w&_E;cLqT2E0E2m7RInRGEbE<-FK?T;(2ZTaRt}Y^R%BL}Ns$wmWNm z%!>RbCl@VnaB^pnOvE@^^pbP;y3#C6kV*-fX{P>SxsYN_27f|2)uegdNZeYX$a7bj zhE?hCc}ii7#wrQsb_|-n?lI9)Q)1F&N%1SANj^G{M%F-mVn<7(5y2%2wJ)GiF771T zoJ1HHVuzOQGcmT8z8O$!&Kz|l)w1FV6+pR*d`8+ACkdR3Fv z0s`)8ud7!hv8F_gI7@Lyw6xTXw!3K4>}PWcUw?82Dld2Eh%9ZIyQ~Fq3NtK7{N0*y zP0~}d#^8JLke}YRf>G5y%Q>MK>q-G%p~scs|0a-MPOn~jP`=Kn_nRD9y%#S|WA0b8 z>HPrZ2qIV9?I}5~(l3j5)b;iC0R^G+w6v7XTtY%km}sr%mit=W!~Wm?L(lnV0Y&Xb_W2_i3v z2Y?UKvE#6xZ)x&;Xe6m7p}8iaoe7`0$a2=Y?uOg&r?3H`ikT=~<~!qg9dPM(L|^33 zVS=i6?{V^@S`AUh?Zb#PID=g&!9}3&xdTTKv+0@m1O5n22c$O1v#P-Dw|vW!3@D0B zsg)Y$iyhtFR}y_qXPwOLq-?IJr7d{eUdrZ6(2F?f)M#fQLIN|j^Cb;5kL*{wDf)yx zmShe)#J0(2uP$y(o-i9-kS^1VAV7Wzw8q5H`8W9sQlMsHeUnDCObGo#ZrDr~w63p4 z2JlXX3U4zSKLq@~*3-vBl_t-cDDSC$Ru zEL^L|8EM>S-Q7?*=6?PQCFh3R2%TqKq4)`I;N;ilKHaWWf^ese ztm9Bui-lB-hYEq_-I-|75V#uWvzbX#Pt2!}STtZm!FeoB!7^-5tp~f-E|KqPJr%Pj zdG5Ag(i67|W?&KG*w1Eu?g1F<85Wg?7i<&HTAtKz-QP|ahM2{*Xbo_S+*f9G7 zq-euzeR3#^CsUU|!Uo6(0=^mh#fmQWlYw>*lfz&fAI%Om52@)HpZKJ9Db}QIM;PG7 zZDm5O$korl$P1o>`0Wa&F1gxI!PTmPABl5=tDb%}DTSS= z(yU_G%l%gWZ^;Vl^R%nVuz_vS+_KdJ=53cj8r4aA>1CE>fgjbcrqjL8hP}HqjaRwx zQ~3ovy{uz9^$*7=SrR46S)ojt2(c0$pTd4)q7POitF-`#!Bz(W*v&8vKrOHMI1HgxQWUdL?QLOou(_f=P2 zd%PVi>D(fi@;wT5OQm{mwWeOoZLJIU8{&3m^=?#6o@lhD_81prOed{uaD$e>W;ME` ztCKvPQsu0XgpTY3&?wlFe_jrwO?3jH9SWibC0X+K(|7N}znysfn2@#TmbyoD!OKfW zT>M=9B7eQ(-0S|C*AvZ9V}$h6$JpXq)r9+TyRO!Zz8ML^rgnk#fy6vba8qdCd?EuR zIw;p^-DW-JDHT$7K;*6ywwx3vT}X28+&k`^@+y)p^13DMd#h%?bdkKi`8F_2M=kD` z8a3s#_s#@LP0cxOc&X-5ezP^P=`&RkIkxy|ZJ@KXpD>L)jAD<0WxxyIP&C(!QifYw|$ShO8VFH zhg2R=)h9bfyH?_Mxzqqu%1u_Mq{Z>U?n2_Lh3GuAn5Pc}{=sQv1&hsJb+5?4kSkld z8304Bq>%!$+X@^p!UT;=rm1i8BR?=ZjU7~brs^ZTJeR6=78e~z!8)-bToIBp06C$Y z;W9X}x;{1Jcrvf~Y;B3A>d$cnSC1>2j{5<>SuJZMd+wWIv+8e=>Ve5=6m6S~Xe~cr zb{T{dZd%rqj%_;5Cyc%?Va{LjH z#J^Vt73QKN^z`bFwz0z?AGIK)@5_sHAS8#|t8zg!A_-*ly?Ua(R4pZ2j3+pKa`s+*(|T;^rmht^y7n<`wUfB; ziOMRRH;Vr?)f!nI*pwNWi(U{=%gXeoI^)3ghcv7Au}rjKNYT1)n$=x-so{I%g86-U}PEkp7BVh1NmaQZE>KQpe@$R zGl_$o3zs`zHvuR!mGfSOv{_z8(UIMeo_+?}(AFAlibC(od+wK!?=sMBR)i!%UZ$Z6 z_4a`fEWCq!hdnu^=u`9q`s944yk=Mh-c#pKb zZl#oN`dXz;Zd$fweM$Xdihwz!mcb5I1I(M~Md6pPc8{=bfh_@G^)uj7igM&SXsKi+ zdOJB3GfG!JStyrfO&J0+@D+d#!EXQw9=Uf5vS9E3DZKDMF_?e;tqfE? zIt}j~v=pnAuh2}nXZ&mYuQl*27aipT8FvA)?)BVi-GM`gG)|cPP)5hog;s(Oq?c_! z0IG>-I!u~Un6AdEx~|U7z8CGhW7+&~Rn^}hz$Wm29s)FN#LQ%hU%nS}Dpl#?EACm^ z#~?B5ps(I#yJO=|`uh5sSdFbm9Lg{KN^WAuXKo}PU9~#0G5dIG7?p{iUHN_bc>~xs zf3Cap{Q>FQrw^v<)dG$|OvmXc)qA^M+5PWBg1-MTB-qDM{|0~r|Frqvg#`7Q{~sVh zGW9=#1kbkouRwy^2CCZBP6+B%9;5`p8k;Du;vi{+`is~xvE(?y!>pj1aIw(N1^xxx z^CLIO`mScJ{WR|kp4C2H7C0%y8BY6=69oZHOAHoTq=lt;lo%iIUS@dG_RATZjY$!* zJf$vAcgO{ulDXG$i^#>{tIAr_)qhoz&unIHKfgiAzPljErp&p4)~wttj1{|T^J|ye z6dC<}V%9w`LVw?cr#2S-HS^8Lgj4>@h&}Dz{NE$8`Istsy_1GB4w2RT=Tu~X;q2I% zM#VBu)YPGI7>Gsc*S7JQezCS8e0@MgC#{Rz({ekc25Tqp#9}o*1*=@sH3C@9lm9OhcZn$H0=Ks4TN zbo|+`jd!*)$iLL*v}8Cg3fIJK5s7oE38i&Gi20mrgYc@dSlSboI3Jr718q&EC^%Qp zu&QJqrB73lk*wQ3N)`MtoMY5;_vgL@!xKMXqYuiNx?--1KXoZ^ydbhE`{l1w7Jzwh z2%O5*fK(AH9IL{?b8V4@;!ficjRh;~qr9HZ#aGBZb)h#8JKAGzN7_56&Rf1%$v|=M z-69%c!*8Re;ud3Zj+kQywhvZ7U8ohviq9zHV3w~|R-+cP6)?QDtZRL&=Z{?Q3dNtP zp7)8;KqY&aI`6hloijpoKS?Z%9E5fyeT3hI^$o-l^`+eO7D-py3fKuqkzHh-A2xM7 z&$!h>MGV*Zdbp4n4I~W%(IF0~wqN&^<&~LLaT1ChPwvZ}c180h6x<0-5M+RcEq>6qmVn80~0Q{+U=Q z=OG4?YpglJ?!HeBm!z84!(jLmQN{U)8f>9mk8WB`M`d8ina*{G4#WCM$0+|Us#HW| zes4vNY?FL^eJuZ&ds)15?@<_(rULV%gnK#NH2=~r=# z^TH~JrP;YgVJ92WsIwrfVQlks@A!@>^Z=h+h{r`0zd;CD{R>j;cv+juHf&R%k^;~m zGqC|6+X~BFDx0jv{$WWkJ$8)Zp0QavnE7;^d&c{uj?Gfa`=@KidJI-d>n0E(w+wPa zuK!i>V;*OksAR1uE$P~1@H$yZZBNOchT{c~S+FwnRkMS1!Dh1e&qdOW&g5KlHED0vq&RrdU}5qjz-su1h7@@{r*n}fGr*mdzCOp!LER&7S5YdI|{AHFAcOy*!#T=JPU z=bxq2|B}ee!ya`!)=_8UrZldQBIM*;KkteFlct|`e8i~lXYc|%G2v*qAMebTaYHY~>gP_D6& zTbjXL8!#2qx)utHT&G6gbTQz+9MctD#&*kct!5gsbLVff#qs~PUG|TE$L{|xD%XEk z8Zf!&7!?(D5+qt`*cc2=QkR(p_7B&MAVL7Xd7>s80q~KN;#FKnha2cixp!em9BNe7 z(OWFDRbc1_=Pkhf+bQ!nM=?BknP5$caBj- z{K;kO3i_B$;NbRLbhA$H!U88O%Ks$vWuf_iM-0zuM!Pg|Ct$g4`v?Bi;EtZn3S`>j zfiPm1qeEl#uAdtstjWu>e!zZ)Gj)3g^7_Ng!mgpfUtjvpXCY;-d|HiMd_&#BTE1I!j5v!Ye-dC+VpeX+W`gqMk`r ziztj6RCUWemEc!iCVq4efbL2&#=8u#4bHfUZexO;g{cY|7mr%Ci7Trs0uL+cRzNJSxoRW$ztCQ(vvgI1EL0hhcWF-GSlQyW7i1Qc;0c~ zMuY#6Pt7CMQdV^FYhrHU$CbQ>ur|@{E^zFXazwBHzEb&y3U8BrkK?@K^>ys__k8s2 z?IVmgICJK-)hv`Mj$L#5>FRNx>G68F4Zgs-`LOodl-M;1QnVZd zZKPBxWgF4JK}psfMNVo&QXxHY5H)rfQ~k{2fd!wL@7z;u7@DJ#=H*`PVvw zCWUToQ5MrWllAUJeejt~xBY8_9)8sA?eH)bfNF2^v#i&42Bv;))NYww+1@69_N z($#jZ8w_#ppQSKseb{$Ib;dAl#ngKmlxE9p7x5`+dgFMQ_R2i#YQ7+m5~dBqfoa?I zNj?Xu8W4B`f2n{p8Q-jU=uXK$*iuX$n*8X6%X5Gjs0Ja__PHE?H#O=|2~fF?f|t3O zT4qiv6CU~Z9-EshaVWlPKj^C^&4(N2*=FX1Jjl!UUJh|PRWuj_g6ibG@ZX5!6=Dn= zAsROc>bo>gIT;`vl%E#vBFs;N)*4uq!)8UtcBcK0NGx~de}=?z=jz+cE>S==T9%_& zqN9IFe?Rwpd-D$oO2AZ||j;3Pk2);N;o|jQX!I8(Xzjy6iJD05A2 zB4cfI1zc=pd9=x+nD#R&YW>z!dXedlhS-^@`&1%V2g3Q|rP*5a!=nAo?O+{paPb-#ZISvzeA1^TppIAGUBV(8qu6l{R04V!v2KTY4uixjQ{$;%t@ z!5WrncouSMzW0)mlU0SdITLL|c-ULeI->FNiZ^4$%Hf3%>8(8(1Uh(-xN0e48Fmi!abSRpk!+T9p| zsenjco=Fr+6WYwqfa(B9H_d6JszU1A?B1GXs_NX|vywOtV8yJlji60~g)gR$<>CD& z*DCUB=HVA_1($U^4%+|htNhSlJslu5-e7c7FXTLBLE5Za;bo!?b$H;RrKl0&c?#gv zk3*(eS3Q!RMhRiGs3njX2J&@<=T;`nkB_p5;H*2_{u!196p?EMwmGd_G)d|i%v_s2 zrVAl<7myhKM5+Y_6~oWZ7RVFNyxcZB>hmhWYFztS(r@U_oKFzRDgco`aCx5T{3 zSAZQhc_B>HFFd|6DVpCb=r?RD*)bBdQ9uau8(u?-OYPhBdm^_{D+8La8AAil!(1r0 zszW&aM1kMUS3umRn(hl^ws!gFajTDi`7+|~yI!XFFM;JJl13Lsn512QpdJ5-F{YFZ zfWDIZyS_BbL27(u0O-)Ia)Yf(jb~tS4PYz%mID~EpCMvo81VU5F%SN;hKWy=HCa~U zk`IRyECE}r=3lKKnV}@5Tc|*Ol37Vvh<|-wR)~40;;bwN^nb`Y`)@Y>{tJ(n8GZW8emM8L6V z?i!TJW-^()0dU=OMmT{jJ!f3KS^@atu+~;4jto=-jB;QioV0cI5=-x*#$mW@VFvU6 zhmSo2FP9|ep%=a(`t>z5fq<`na^FhvOgo}8b&WuP)g|4)TY&aRfr0`c{Szn46rD#+ znF0sZ$n~n>druiqCTEbfMXlPS;%iqYgHXa3GI|}rzRR{MZ^^TtXUeqXuWYOEs70%( zap+8zG>Ms2=hErRecimuK{00OU6Z24@+k@Z z=1Il5tg!dzYMF*`*-_llze&?gQq@(!DO>7DJ7YIR5v#%#AiDIi=ymP%B8(K?vB}w( z`-u*mu)qCqAE*@>wunH%Qji;lAfYb#y@J=uYqhzVl*N}v`;6+ogFTS9{}l`T1aY`v zFnc26L$gX(euZb6dFW8|&S~C^2H=f84DC$>r81kyHZz zN4t>+G{WpcGATlRbuF8)`Xqr`(h%B9Q18++0E$<2r3N~>aFT1MvW1vLWgxeCWEv4? zk2A{v$su>gFK=r(tx-azwV0#R%}pbPId0#28+4Tv6zlP3o^(75oM<6VFiL9Lz+V+CQ&!nhjiOmvf=Yyf z_nWHH?1n2O^xYy#PB(=2f7v_V_yL5GV=hi6uq_Z%}u*_i5lk&kAX;1 zB=~RY(o!r`gbf>HY*2?O?tz6$(y1igw3i7^JW0^o%yC+Mrw}ve3~M^-VF9gpJX^A` zkw%s3C1Hv)_*v`^$VH3jL7eEHH~7+90Kv}G>B%mFX;rvoVHt|42aJ~A-ab>6Wn&&3rtq1B9l%mziOl5DWV%y>)NH+ z2Q2GR3&*Igh`fK<@UW!X4v{pV15{uxse*?6yzg0{^al%DVoV+yNX{+%N&>f(udO5I zXgKMQ5)q!TdQ{D?i!wgv=YJ?ib9ICo)L06vPY-c_1M^D#0-OWoyfIpBkk&pC76oa^4W%OpVWeHCByPwdzDGyHL}9PmoZ9I6l`C{2 z=l|OEJKgbjH1(uE@QZIcJ~{sA&2PP{l>YrZXa4d3ztHSodp84zv2t_QzTf}du3EkB zQ~o92rI*ew{^$GWiTLN&=kNbf`1g3;qqgA1_La7Eo6=S8{qe23dv;IA-`%sT&J zr5P$c0a84wp{KO{IW=a{tL(JFg}K9L$Xv@-;CfkLNq@j^IjE=y)*AojZ5 zcHCGhjmzI|`y}3MshmDT! z)U_ZI90kDUM*Y`({iFZ?EdTtmIb2+N_Le`p|Gm9GJ^RY-SFf_-T$U-@%$~PJF0&S> zry&it)yaM@@U&u&Wy-d*XNB%!O9*3NUC*pZ|6(s+uU_ucvW;F9gYxoWpCf?zv;P0@A9vr^U5CkCN?-XKxK0W*>v`j*-0BctPxl*NwYpqV zieHvafzH7uq*uQQGF=)TsG>C6d;R$kNL(kRgHN)Eo4*n=QF`FqGEflgwF`!x(K6Q; z)CH)jT^0m!fc0!pJLAhQpQYeRgrUp~)Zlyhb*2|2-Mz{2x|(jFt*vd_e)^mjiamD8 zKY8uHJ{J!D19Av{6ol!Wg+dJf6>fW z;kx>4>GgCiNEX`Y zmA|gn|GjSOeKr2iBXQZoDbJUn8Zwc`>TmqUUB+k{14LGzMfZy5(N_nX+0A+Uk7iY^ ztKM;CI!X}MvTfe9=~D5IH*4^Q6tGykgyKdeQ&evOXVX!F5V-CWXwMYu@^?poSErro z*8r7|*1oUug4!>yz6~r@bCN-!d5Qf~xBfm2`$Zt>Hzq50gUZ_pAf5OB|NH)N_x-=? z{&axG=r>$m@=mSPV(+fG?bB8%ZL;e@ kCgbu%5Lw&Jl4+0rvrjiIUt|5?jwQ(Pp00i_>zopr0H?qcnl3m9I?E*m%D|wMXkYZFx}gD@C#oLT-#FyB zu_d$|r~G+v;&H+rrNo5GSFY@pd=hW+`Gm*;gB^ySA3ZC4dnu>h^@PZl3*@hlw%0j8 zGlve6ZUxZLS}H19a^m-_Q{_yo``eqiVI|ZAqsc^%U>kYk)v%FyI0^`%B8vdA_I_t= z2vcf<-o$;e|H_V&Pxk%mSFLU1N8Ygib$#zT0r}&v8@@t5*2Y} zz@LBJ@ZImOi>cD-G$u0CC2VL z@aN_COeWeM3MG=TUhRi^6#FW+@H+qeqQsP9fu#_qFw}d7m38EIKOj0(-kkA|W0#s(p_d&zFWChYG{(YsaNzpSw2nCeG%+PM}A(n z)(4CTo|2^HT3MY0fbZR&X*c$T<3inc=)_(6TAVQ`$+xxSM2P)G#x{I!f7DbX+X{XL z84}blsQslce+HKDG9@|di2Z$A`84|X@3-R@7a!2rRl-~Vk05N9|KnNkcEupX#QmCm(Ld#Jn(mliP6D+B39`V`8nn=tc0udBb&2_Kvh_*Gd)06%^jwi zsVgjZ-gRds8U%ccnSckY6-@l%Vs8e_0tO}S9%X%3gcDANjM zd3-g+^*59@a^kKsK4E+KPZ$ef?OAi$k1@tsk1m@;Z!PI4_HYw5uSU7nV!>oBzZm&y z7-~AaPH+j;8}ydir#UEik4i!-?D2*BA0}KB+gZisaxdE%y=rwzr>5+YJre!k9HcGk zuHjhQ5fx%t>}119L*!yPt0ZUo6?NIwro2j|_4PHndG@L2&777^rF3&=Z*837~u z#j6H)wN+O~M2{lJbCuXDvFq^$uM5#~VkyDW28m}#X$2P%yXTGI>sCbO=*N3>UDC{l+LSk^M4&@z0>wxDv35k?KyN&Rbb=mjH88rWz6$&kLYAoJxXU zZd1hX|Kj?k2~4-bRXf(k_}e;A-VK|!Q`rsd&pXJ*B@JDqPa#%b>;A3sp*@wCer?~O z2Qa2@H*_o8W_IX@t^!MAl^B9M!_tg^QuZ3(v6YEiC?cX&WVA@$Bogwzk8ByeE;N#k z;b3l2N!5{(@c=`^`UD9SZqdfY^*3R9pD-EgRbB$@qM*Et*9dlwn`4R3gY~iX223jL zC_y8wX=U+kz8fglB(v>WgljMH{5hL5yT>GM;l2|-gQd0&UkR}gtnlB4;4{(UBVioii!;?#9^u2e7D6d^`0I>i)8%eQih1%b}yxZ0osti zpYoqkWuDG84G=AKv_UbnOh>TS>*a>i8>Up}l5UWLk5F|pjHAjpMY&+4IuvUNVq%QH zo-tJIM5J-EQ-hNLb$NAdGYF_qaVE^UlYaLrx1yoRHM6{Xi5-5PT!zC8-*5M{e8EU# zu6DgrFoBiKdJLMbpq}P9h=zvNI0`?la#@{;;MwDcrM0C?v#kjnvdG%ba2S2J8jgbf zZiK;Vk%IcLMShO?0R;41jaMAYt2i+wRI8-hBLYs!k$kQJC;8*My-4fzMg&`lgriA0 zbMcANy>g?EXP$s@`g-})tb?9`tIX^xcR|c-YgHuh=z=TBQgSu9+Nr~lviF4i87Z^A zuqQuSTiuRGSR{=NG@1T5x8wWC=ra(`(NIi9g}W2mTJ@a{H$gp3dcw906);$ZOK86839a>FaE6ldebzop z=m~4t)<>2$XkZNp^^d_O_Nv;8vJhsR81FW>Co9SG)^|hOLKkvd9Ri6tNWnBl?6TKW zxP)9brlMt`tP0}UC7enl-8I)={7HDrUW^4@%W{e%T#w1(%-)=EwO+5q&86b7bxxe4 zjH5R79<^2)4YMAQK-f53Z4L(^5y=>IH^chf^xbaldYm&yc#h;8@qwW{?xG>f8De|* z(@re!sqk!F=w^|z{m=UoV5Oq3K6w}co^#@Z{nSv;EH=!sTvbFXWJ(oNioqU^x#I6X zYZ1{s_Hg|v9d>B;3jHSh($3j;FJrIKJ`-rds;nS1>NVc_4kAcoA*E1dZ!WB{=}tYQ zsa3J<{r;oKqlph!9!XST#s=klTn)Q*4#h>yZ!gZ%U>T`Y4 z>t{0sRFWKSHB& z>{!Cfr7NJZFUA@QiT?Gn1yH>ehWtQU_~xdLx12&uOSXZuhAvfmG4^ltZhrugLmd zxqd#vVaI-Q)nk;|YLO1A+~LX7*RWaeV|pN^EQj(*d!TQiPJ>4rsa)w?WtF-sVif!1nZ%@;jIi#%(+9Dl#QC*g2MxUF? z;oT?P-*ugpR$GII!%{#OQ1n@Lsox>!{iadsrP_ueF;w|##B#t)03ZKoh;F@GIPTp# zZn}TFTK*)2!Wv%4q_xK1j7gONBnBiJz*pLU8+6wIY5uP)_{ zHmpySl&B%*-qx%(dAaUcrtj4E3&WU>ChxX4Ggy@eNTFD$SW3>@S04I^D=Nd6`Va)J z%gR%d16y?N_DyXcjYr>){An%91+5Fs zv6Z!Hq+mm4&FTV5yq>x^Xlki>p{Bd$QewTIkSr#H{50;^Q9J}lfUR=!8fJLq#YRgw z$t3K}3S>allHyb<+POP$FIu*zFUTNBEMDOKQ>Ye$21W7aAatxqE}0<1$cv#Xu7 zSId~kBuT*B-b9_*hFn(CNUxTC^rAiL5Z&(*>Yw+l+^FdNuGtw%Fu@wH+-8bUAI2YGcza7EF&c%HVs4l<4 znZwGg1)xo$uFA#n47b1L+Byd|BeF8!6DHi?{f#yeJiq8ayjEd=v4+jVSZy|>rQ-F8 zkoifmCbPh1tkk)tHO1bA<@I2{mlqVmUp72BJU@-D_7nE=086o_ zVt$VDEhh$U8<+os$xML+jOBtS)dMWPHg)-bSjc)nB855mW(*AU7!XP_nHU)jj2Jv~ zCw?U)Zy^y7)?f%y!mFW_GNGfaeig}Ao>?`MqfOFKY%C0qo;ONmjW%jrF}-H3}1o?EVVeYJY3+V1d` zUs4Zn3vKpc2|qU^tfN(g*4Lhph~85&Ck`U1#7R|!bG5?HTfK>K>$1imsG-%Tfq4lC zcddBuzLsCTQ?8;P1-ShnF5@M`^l@pSSf7{7E>C?#4O05d+@E zjmn)`!)SZMFOy}89Y6#~;LIxe-c%!tG8efT8Hy`nWz}fUorZHh^{btNwD=xC9w?J8 zTK6eqZNv91eg#3yI@!~qMs~R-9gh2&ZfMDEZfbXTcXQ;BudVIjnAe95k*lxL`e^|> z4J&}T%Z7<}AvDb|a0ofD$+`B?>w^bgJ^D-=@KD2ao}asJdGF;eW5f3DBX=YG9w+1~ zBGr{1w!y=b17Q-!oQ@NO<>m%OM;T)zecn!y6y;CJn?H?BKl(7-p>GUZK0xe}teBE2 zRY<~^HD=dWUxIBA!m~6|ddw6`l9pGKrW6DmRHJl0`Ix^RJ|n7+QV7#pAN;hcrhHt}YSbKbypMnCHYy8yiSM$gVf~ zN#%zl5`er#$H{VO%=mTJ>V{D3io4oJwFZrbuzK$roX)IxYZ2#iR<6aJ|c&`Arl z7v$sn-u`vBxD9%A((cAL6|)eQ?ph`1m4}Fo@xkHKkjRoHlw|wy3wM+EBdLuq4-bd< zXyu2NJFUE7y50L-9vc;Y_;%hnnU~bgl#2CBRyW zNGfZlm!2bjSomXF=S|?#6n&=q&OoZ1B{U)@(|La3PH#T-UF>K;K%btO;JvZ)?f8vo zx2rc1gU=*!sT!U=0g<$)AjE{Q>kF`e6skY&N3Aya+w=Z|?cd!?=z{pYEM+02kmjIq z52YrYD7Sm9mgqaVS}Go;fo!Y+Yt@-*P0f!dq*}iO5zu6n=M8*0Q=b)Cy?88fI@nn=Q_rIsvy$yrF(y3~fdWU0b=i0SZzIK5ya&+GnoQ9hyLF3gBf z_b^whxu+E-y0iA@`MT?QX?c{IH45IaXAtWwJcp9}|-o7G$DQLz^cjpM6Xzlq%Ld zVBIK&V?9z{v}s`Y%{<;L&l^8)6zd4o+d2Dhj3zovxg6dYk^kU36ojPp_tE z(S*7))9;cy*@cK9B+_yOv{_C@&%-Rzv@b%5L+UQm}rLdg0xCRUzL z#}=571}|ZZ*^w2697|`5FEHXG2F{a#|UPjkp;h~D73mahTj1&9fn+xXmvgM4^hWRH?A=RVt z8*PRV6x)Wq=C_nF%9@jaM2w&ML!_Ea2qR!aymbcMOZ3`Qk8!8N=hTE57ir8LZ!c)| zO#Zl=2==FkRft1Rm94tzkLOd-%uv#_=Y@dwZU~X~OkJ`D8jJ@m!-MH{0+yid2FsmR=KL)bE2y4LJuTRNHSuDZStq!ZQ9L+YGCUqf! zNvY#;%@>hGO>fRIPC+n*A3{dKuQC?i0QV$svdzeIc4@BnfbLmw@T4ofwn`@%81M=# zB^&NXR#bO)NJxMc9(dv~8+b>h#3Lcf#T;QtH_}bRX_n*+)1(aPycOxGanhTd`GpLNP=8s; z5lJl-I##CP*tfNsSKsE@u->K%$k$$JX+a_MxELx}G<<6j1{nYdeDKmY&+O~i0aF;c zk3KhYU(RwYs0SHB@I)}irv~!I$K%pcOG;U0{>v-t7nd zIq7m&rowfaTlPpFdaz(;OOGEptvq*9?E{{n zrWzO#X)cf&NQ>Zypu8qf#r#9t@WcFpuJ}$tFaGm3MZQi)3qrq>w+?Du{6~^^8?x$q+Qk#-}Af+A?CHDmGS>SEnefq3EN>Z{|~d7mgmd z{s{d*@)|jxA0p7C9FqnBW^7L;DHwiU8WKpZMik#7MgSj+!T!U%Me{>aYpA3WwNdpI z32b&~R)F}RZ2>?sm0`UBj(TSLr(fp*nKPLW(u)ruJ8r4D5a;a>U-|bA(unb8egSt<<})QicB3Ts=E|@)VB%x zHe{doXGcq#gvCZP(xnrGy6xxksCh8c7H$C*&4CeuMwJeg(EC>|zZo&$^k @WQo} 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

()rB*;{C)`G|jbYQNG1b4i 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 From 1449e98757bccf4470cc832e0c5e3d0f7632005b Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 8 Feb 2016 12:32:11 +0100 Subject: [PATCH 10/68] Move OAuth languages strings to OAuth plugin --- languages.yaml | 127 ------------------------------------------------- 1 file changed, 127 deletions(-) diff --git a/languages.yaml b/languages.yaml index 4d3bd2c..ed4fcff 100644 --- a/languages.yaml +++ b/languages.yaml @@ -2,80 +2,44 @@ en: PLUGIN_LOGIN: USERNAME: Username PASSWORD: Password - ACCESS_DENIED: Access denied... LOGIN_FAILED: Login failed... LOGIN_SUCCESSFUL: You have been successfully logged in. - BTN_LOGIN: Login BTN_LOGOUT: Logout BTN_FORGOT: Forgot BTN_REGISTER: Register - SESSION: "“Remember Me”-Session" REMEMBER_ME: Remember Me REMEMBER_ME_HELP: "Sets a persistent cookie on your browser to allow persistent-login authentication between sessions." REMEMBER_ME_STOLEN_COOKIE: "Someone else has used your login information to access this page! All sessions were logged out. Please log in with your credentials and check your data." - - OAUTH_LOGIN: Sign in with %s - OAUTH_SIGNIN: Sign in with your username and password - OAUTH_CONNECT_MESSAGE: Connect with a social network - OAUTH_CONNECT_MESSAGE_EXTRA: other social networks - OAUTH_PROVIDER_NOT_SUPPORTED: OAuth provider "%s" is not supported - OR: or - BUILTIN_CSS: Use built in CSS BUILTIN_CSS_HELP: Include the CSS provided by the admin plugin ROUTE: Login path ROUTE_HELP: Custom route to a custom login page that your theme provides ROUTE_REGISTER: Registration path ROUTE_REGISTER_HELP: Route to the registration page. Set this if you want to use the built-in registration page. Leave it empty if you have your own registration form - - OAUTH_SECTION: OAuth - OAUTH_ENABLE: Enable OAuth - OAUTH_USER_AUTOCREATE: Auto-create user account - OAUTH_ACCESS: OAuth user access rights - OAUTH_PROVIDER_SECTION: OAuth providers - OAUTH_PROVIDER_FACEBOOK: Enable Facebook OAuth - OAUTH_PROVIDER_GOOGLE: Enable Google OAuth - OAUTH_PROVIDER_GITHUB: Enable GitHub OAuth - OAUTH_PROVIDER_TWITTER: Enable Twitter OAuth - OAUTH_CLIENT_ID: Client ID - OAUTH_CLIENT_SECRET: Client secret - - FACEBOOK: Facebook - GOOGLE: Google - GITHUB: GitHub - TWITTER: Twitter - USERNAME_NOT_VALID: "Username should be between 3 and 16 characters, including lowercase letters, numbers, underscores, and hyphens. Uppercase letters, spaces, and special characters are not allowed" USERNAME_NOT_AVAILABLE: "Username %s already exists, please pick another username" PASSWORD_NOT_VALID: "Password must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters" PASSWORDS_DO_NOT_MATCH: "Passwords do not match. Double-check you entered the same password twice" - EMAIL_NOT_CONFIGURED: "Email not configured" USER_NEEDS_EMAIL_FIELD: "The user needs an email field" EMAIL_SENDING_FAILURE: "An error occurred while sending the email" - ACTIVATION_EMAIL_SUBJECT: "Activate your account on %s" ACTIVATION_EMAIL_BODY: "Hi %s, click %s to activate your account on %s" WELCOME_EMAIL_SUBJECT: "Welcome to %s" WELCOME_EMAIL_BODY: "Hi %s, welcome to %s!" - NOTIFICATION_EMAIL_SUBJECT: "New user on %s" NOTIFICATION_EMAIL_BODY: "Hi, a new user registered on %s. Username: %s, email: %s" - EMAIL_FOOTER: "GetGrav.org" ACTIVATION_LINK_EXPIRED: "Activation link expired" USER_ACTIVATED_SUCCESSFULLY: "User activated successfully" INVALID_REQUEST: "Invalid request" - USER_REGISTRATION: "User Registration" USER_REGISTRATION_ENABLED_HELP: "Enable the user registration" - VALIDATE_PASSWORD1_AND_PASSWORD2: "Validate double entered password" VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Validate and compare two different fields for the passwords, named `password1` and `password2`. Enable this if you have two password fields in the registration form" - SET_USER_DISABLED: "Set the user as disabled" SET_USER_DISABLED_HELP: "Best used along with the `Send activation email` email. Adds the user to Grav, but sets it as disabled" LOGIN_AFTER_REGISTRATION: "Login the user after registration" @@ -86,21 +50,17 @@ en: SEND_NOTIFICATION_EMAIL_HELP: "Notifies the site admin that a new user has registered. The email will be sent to the `To` field in the Email Plugin configuration" SEND_WELCOME_EMAIL: "Send welcome email" SEND_WELCOME_EMAIL_HELP: "Sends an email to the newly registered user" - DEFAULT_VALUES: "Default values" DEFAULT_VALUES_HELP: "List of field names and values associated, that will be added to the user profile (yaml file) by default, without being configurable by the user. Separate multiple values with a comma, with no spaces between the values" ADDITIONAL_PARAM_KEY: "Parameter" ADDITIONAL_PARAM_VALUE: "Value" - REGISTRATION_FIELDS: "Registration fields" REGISTRATION_FIELDS_HELP: "Add the fields that will be added to the user yaml file. Fields not listed here will not be added even if present in the registration form" REGISTRATION_FIELD_KEY: "Field name" - REDIRECT_AFTER_LOGIN: "Redirect after login" REDIRECT_AFTER_LOGIN_HELP: "Custom route to redirect after login" REDIRECT_AFTER_REGISTRATION: "Redirect after registration" REDIRECT_AFTER_REGISTRATION_HELP: "Custom route to redirect after the registration" - OPTIONS: Options EMAIL_VALIDATION_MESSAGE: "Must be a valid email address" PASSWORD_VALIDATION_MESSAGE: "Password must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters" @@ -112,76 +72,41 @@ fr: ACCESS_DENIED: Accès refusé... LOGIN_FAILED: Échec de la connexion... LOGIN_SUCCESSFUL: Vous vous êtes connecté avec succès. - BTN_LOGIN: Connexion BTN_LOGOUT: Déconnexion BTN_FORGOT: Mot de passe oublié BTN_REGISTER: S'enregister - SESSION: "“Se souvenir de moi” - Session" REMEMBER_ME: Se souvenir de moi REMEMBER_ME_HELP: "Définit un cookie sur votre navigateur pour permettant l'authentification par connexion persistante entre les sessions." REMEMBER_ME_STOLEN_COOKIE: "Quelqu'un d'autre a utilisé vos informations de connexion pour accéder à cette page ! Toutes les sessions ont été déconnectées. Veuillez vous connecter avec vos identifiants et vérifier vos données." - - OAUTH_LOGIN: Se connecter avec %s - OAUTH_SIGNIN: Se connecter avec votre identifiant et mot de passe - OAUTH_CONNECT_MESSAGE: Se connecter avec un réseau social - OAUTH_CONNECT_MESSAGE_EXTRA: d'autres réseaux sociaux - OAUTH_PROVIDER_NOT_SUPPORTED: Le fournisseur OAuth "%s" n'est pas pris en charge - OR: ou - BUILTIN_CSS: Utiliser les CSS intégrés BUILTIN_CSS_HELP: Utiliser les CSS fournis dans le plugin d'administration ROUTE: Chemin de connexion ROUTE_HELP: Chemin personnalisé vers une page de connexion personnalisée proposée par votre thème ROUTE_REGISTER: "Chemin vers l'inscription" ROUTE_REGISTER_HELP: "Chemin vers la page d'inscription. A définir si vous souhaitez utiliser la page d'inscription intégrée. Laisser vide si vous disposez de votre propre formulaire d'inscription." - - OAUTH_SECTION: OAuth - OAUTH_ENABLE: Activer OAuth - OAUTH_USER_AUTOCREATE: Création automatique d'un compte utilisateur - OAUTH_ACCESS: Droits d'accès OAuth de l'utilisateur - OAUTH_PROVIDER_SECTION: Fournisseurs OAuth - OAUTH_PROVIDER_FACEBOOK: OAuth Facebook activé - OAUTH_PROVIDER_GOOGLE: OAuth Google activé - OAUTH_PROVIDER_GITHUB: OAuth GitHub activé - OAUTH_PROVIDER_TWITTER: OAuth Twitter activé - OAUTH_CLIENT_ID: ID Client - OAUTH_CLIENT_SECRET: Secret client - - FACEBOOK: Facebook - GOOGLE: Google - GITHUB: GitHub - TWITTER: Twitter - USERNAME_NOT_VALID: "Le nom d'utilisateur doit comporter entre 3 et 16 caractères et peut être composé de lettres minuscules, de chiffres et de tirets de soulignement (underscores) et des traits d'union. Les lettres majuscules, les espaces et les caractères spéciaux ne sont pas autorisés." USERNAME_NOT_AVAILABLE: "Le nom d'utilisateur %s existe déjà, veuillez en choisir un autre." PASSWORD_NOT_VALID: "Le mot de passe doit-être composé d'au moins un chiffre, une majuscule et une minuscule, et au moins 8 caractères" PASSWORDS_DO_NOT_MATCH: "Les mots de passe sont différents. Réessayez de saisir le même mot de passe deux fois." - EMAIL_NOT_CONFIGURED: "L'e-mail n'est pas configuré" USER_NEEDS_EMAIL_FIELD: "L'utilisateur a besoin d'un champ pour e-mail" EMAIL_SENDING_FAILURE: "Une erreur est survenue lors de l'envoi de l'e-mail." - ACTIVATION_EMAIL_SUBJECT: "Activer votre compte sur %s" ACTIVATION_EMAIL_BODY: "Bonjour %s, cliquez sur %s pour activer votre compte sur %s" WELCOME_EMAIL_SUBJECT: "Bienvenue sur %s" WELCOME_EMAIL_BODY: "Bonjour %s, bienvenue sur %s!" - NOTIFICATION_EMAIL_SUBJECT: "Nouvel utilisateur sur %s" NOTIFICATION_EMAIL_BODY: "Bonjour, un nouvel utilisateur s'est inscrit sur %s. Nom d'utilisateur : %s, e-mail : %s" - EMAIL_FOOTER: "GetGrav.org" ACTIVATION_LINK_EXPIRED: "Le lien d'activation a expiré" USER_ACTIVATED_SUCCESSFULLY: "Utilisateur activé avec succès" INVALID_REQUEST: "Requête invalide" - USER_REGISTRATION: "Inscription de l'utilisateur" USER_REGISTRATION_ENABLED_HELP: "Activer l'inscription des utilisateurs" - VALIDATE_PASSWORD1_AND_PASSWORD2: "Validate double entered password" VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Validate and compare two different fields for the passwords, named `password1` and `password2`. Enable this if you have two password fields in the registration form" - SET_USER_DISABLED: "Définir l'utilisateur comme désactivé" SET_USER_DISABLED_HELP: "Best used along with the `Send activation email` email. Adds the user to Grav, but sets it as disabled" LOGIN_AFTER_REGISTRATION: "Connecte l'utilisateur après son inscription" @@ -192,21 +117,17 @@ fr: SEND_NOTIFICATION_EMAIL_HELP: "Notifies the site admin that a new user has registered. The email will be sent to the `To` field in the Email Plugin configuration" SEND_WELCOME_EMAIL: "Envoyer un e-mail de bienvenue" SEND_WELCOME_EMAIL_HELP: "Envoyer un e-mail à un nouvel utilisateur enregistré." - DEFAULT_VALUES: "Valeurs par défaut" DEFAULT_VALUES_HELP: "Liste des noms et valeurs associés pour les champs. Ils seront ajoutés au profil utilisateur par défaut (fichier yaml), sans pouvoir être configurables par l'utilisateur. Séparez les différentes valeurs par une virgule, sans espaces entre les valeurs." ADDITIONAL_PARAM_KEY: "Paramètre" ADDITIONAL_PARAM_VALUE: "Valeur" - REGISTRATION_FIELDS: "Champs d'inscription" REGISTRATION_FIELDS_HELP: "Ajouter les champs qui seront ajoutés au fichier yaml de l'utilisateur. Les champs non listés ne seront pas ajoutés même s'ils sont présent sur le formulaire d'inscription" REGISTRATION_FIELD_KEY: "Nom du champ" - REDIRECT_AFTER_LOGIN: "Redirection après connexion" REDIRECT_AFTER_LOGIN_HELP: "Chemin personnalisé de redirection après la connexion" REDIRECT_AFTER_REGISTRATION: "Redirection après inscription" REDIRECT_AFTER_REGISTRATION_HELP: "Chemin personnalisé de redirection après l'inscription" - OPTIONS: Options EMAIL_VALIDATION_MESSAGE: "Doit-être une adresse e-mail valide" PASSWORD_VALIDATION_MESSAGE: "Le mot de passe doit-être composé d'au moins un chiffre, une majuscule et une minuscule, et au moins 8 caractères" @@ -215,48 +136,30 @@ hr: PLUGIN_LOGIN: ACCESS_DENIED: Pristup odbijen... LOGIN_FAILED: Prijava nije uspjela... - BTN_LOGIN: Prijava BTN_LOGOUT: Odjava BTN_FORGOT: Zaboravih BTN_REGISTER: Registriraj - REMEMBER_ME: Zapamti me - - OAUTH_LOGIN: Prijavi se sa %s - OAUTH_SIGNIN: Prijavi se sa svojim korisničkim imenom i lozinkom - OAUTH_CONNECT_MESSAGE: Poveži se preko socijalnih mreža - OAUTH_CONNECT_MESSAGE_EXTRA: druge socijalne mreže - OAUTH_PROVIDER_NOT_SUPPORTED: OAuth provider "%s" nije podržan - OR: ili - BUILTIN_CSS: Koristi ugrađeni CSS BUILTIN_CSS_HELP: Uključi CSS koji dolazi sa admin pluginom ROUTE: Putanja prijave - ROUTE_REGISTER: Putanja registracije - - USERNAME_NOT_VALID: "Korisničko ime bi trebalo biti između 3 i 16 znakova, uključujući mala slova, brojeve, _, i crtice. VELIKA SLOVA, razmaci, i posebni znakovi nisu dopušteni" USERNAME_NOT_AVAILABLE: "Korisničko ime %s već postoji, odaberi neko drugo" PASSWORD_NOT_VALID: "Lozinka mora sadržavati bar jedan broj i jedno veliko i malo slovo, i bar još 8 ili više znakova" PASSWORDS_DO_NOT_MATCH: "Lozinke se ne slažu. Poonovo provjeri da li si unio istu lozinku dva puta" - EMAIL_NOT_CONFIGURED: "Email nije konfiguriran" USER_NEEDS_EMAIL_FIELD: "Korisnik treba email polje" EMAIL_SENDING_FAILURE: "Došlo je do greške pri slanju emaila" - EMAIL_FOOTER: "GetGrav.org" ACTIVATION_LINK_EXPIRED: "Aktivacijski link je istekao" USER_ACTIVATED_SUCCESSFULLY: "Korisnik je uspješno aktiviran" INVALID_REQUEST: "Nevaljani zahtjev" - USER_REGISTRATION: "Registracija korisnika" USER_REGISTRATION_ENABLED_HELP: "Omogući registraciju korisnika" - VALIDATE_PASSWORD1_AND_PASSWORD2: "Validiraj duplo unesenu lozinku" VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Validiraj i usporedi dva različčita polja za lozinke, imenovana `lozinka1` i `lozinka2`. Omogući ovo ako imaš dva polja za lozinke u formularu registracije" - LOGIN_AFTER_REGISTRATION: "Ulogiraj korisnika nakon reegistracije" LOGIN_AFTER_REGISTRATION_HELP: "Ulogiraj korisnika odmah nakon registracije. Ako je potrebna email aktivacija, korisnik će biti ulogiran odmah nakon aktiviranja računa" SEND_ACTIVATION_EMAIL: "Pošalji aktivacijski email" @@ -265,16 +168,13 @@ hr: SEND_NOTIFICATION_EMAIL_HELP: "Obavještava administratora da se novi korisnik registrirao. Email će biti poslan na `To` polje u Email Plugin konfiguraciji" SEND_WELCOME_EMAIL: "Pošalji email dobrodošlice" SEND_WELCOME_EMAIL_HELP: "Šalje email novoregistriranom korisniku" - DEFAULT_VALUES: "Određene vrijednosti" DEFAULT_VALUES_HELP: "List of field names and values associated, that will be added to the user profile (yaml file) by default, without being configurable by the user. Separate multiple values with a comma, with no spaces between the values" ADDITIONAL_PARAM_KEY: "Parametar" ADDITIONAL_PARAM_VALUE: "Vrijednost" - REGISTRATION_FIELDS: "Registracijska polja" REGISTRATION_FIELDS_HELP: "Add the fields that will be added to the user yaml file. Fields not listed here will not be added even if present in the registration form" REGISTRATION_FIELD_KEY: "Ime polja" - OPTIONS: Opcije hu: @@ -287,42 +187,15 @@ hu: BTN_FORGOT: Elfelejtettem BTN_REGISTER: Regisztráció SESSION: "Munkamenet Megjegyzése" - REMEMBER_ME: Jegyezz Meg REMEMBER_ME_HELP: "Elhelyezünk egy hosszú lejáratú sütit a böngésződben, hogy belépve maradhass két munkamenet között." REMEMBER_ME_STOLEN_COOKIE: "Valaki a belépési adataid felhasználásával látogatta meg ezt az oldalt! Minden munkamenetet kiléptettünk. Kérlek, jelentkezz be ismét és ellenőrizd az adataidat." - - OAUTH_LOGIN: Belépés %s használatával - OAUTH_SIGNIN: Belépés felhasználóneved és jelszavad megadásával - OAUTH_CONNECT_MESSAGE: Összekapcsolás egy közösségi oldallal - OAUTH_CONNECT_MESSAGE_EXTRA: más közösségi oldalak - OAUTH_PROVIDER_NOT_SUPPORTED: A(z) "%s" OAuth szolgáltató nem használható - OR: vagy - BUILTIN_CSS: Beépített CSS használata BUILTIN_CSS_HELP: Az admin plugin által biztosított CSS beillesztése ROUTE: Belépés útvonala ROUTE_HELP: Egyedi útvonal egy egyedi belépő oldalhoz, melyet az aktuális téma biztosít ROUTE_REGISTER: Regisztráció útvonala ROUTE_REGISTER_HELP: A regisztrációs oldal elérési útja. Akkor állítsd be, ha a beépített regisztrációs oldalt szeretnéd használni - - OAUTH_SECTION: OAuth - OAUTH_ENABLE: OAuth engedélyezése - OAUTH_USER_AUTOCREATE: Felhasználói fiók automatikus létrehozása - OAUTH_ACCESS: OAuth felhasználók jogai - OAUTH_PROVIDER_SECTION: OAuth szolgáltatók - OAUTH_PROVIDER_FACEBOOK: Facebook OAuth Enegdélyezése - OAUTH_PROVIDER_GOOGLE: Google OAuth Engedélyezése - OAUTH_PROVIDER_GITHUB: GitHub OAuth Engedélyezése - OAUTH_PROVIDER_TWITTER: Twitter OAuth Engeédlyezése - OAUTH_CLIENT_ID: Client ID - OAUTH_CLIENT_SECRET: Client secret - - FACEBOOK: Facebook - GOOGLE: Google - GITHUB: GitHub - TWITTER: Twitter - USERNAME_NOT_VALID: "A felhasználónév 3-16 karakter hosszú legyen, tartalmazhat kisbetűket, számokat, aláhúzást és kötőjelet. Nagybetűk, szóköz és speciális karakterek használata nem megengedett" USERNAME_NOT_AVAILABLE: "%s nevű felhasználó már létezik, kérlek válassz más felhasználónevet" PASSWORD_NOT_VALID: "A jelszónak tartalmaznia kell legalább egy számot, egy kisbetűt és egy nagybetűt, valamint legalább 8 karakter hosszú kell, hogy legyen" From 0c4ebfb21c22ac9159e6eda4f6aae0a2f989b837 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Mon, 8 Feb 2016 15:26:32 -0500 Subject: [PATCH 11/68] Move OAuth css to oauth plugin --- css/login.css | 152 -------------------------------------------------- 1 file changed, 152 deletions(-) diff --git a/css/login.css b/css/login.css index 0e2ca53..2d26583 100644 --- a/css/login.css +++ b/css/login.css @@ -31,78 +31,6 @@ #grav-login .form-actions p { margin-bottom: 0; } -#grav-login .form-oauth .oauth-provider, -#grav-login .form-oauth .oauth-provider-extra { - list-style: outside none none; - margin: 0.5rem 0; - padding: 0; -} -#grav-login .oauth-provider li { - display: inline-block; - padding: 0.25rem; -} -#grav-login .oauth-provider .button { - height: 5rem; - width: 5rem; - opacity: 1; -} - -#grav-login .form-oauth .button:hover { - opacity: 0.75; -} - -#grav-login .form-oauth button.facebook { - background-color: #4c699e; -} -#grav-login .form-oauth button.google { - background-color: #da573b; -} -#grav-login .form-oauth button.twitter { - background-color: #1daee3; -} -#grav-login .form-oauth button.github { - background-color: #5c5853; -} -#grav-login .form-oauth button.bitbucket { - background-color: #205081; -} -#grav-login .form-oauth button.flickr { - background-color: #400090; -} -#grav-login .form-oauth button.microsoft { - background-color: #2672ec; -} - -#grav-login .form-oauth > input { - display: none; -} - -#grav-login .oauth-provider .button { - display: block; - font-size: 0.8rem; - font-weight: bold; - height: 5rem; - line-height: 8rem; - margin: 0; - padding: 0; - position: relative; - text-align: center; - width: 5rem; - color: white; - border: none; -} - -#grav-login .oauth-provider .button i { - bottom: 0; - content: " "; - display: block; - font-size: 3rem; - left: 0; - margin-top: .5rem; - position: absolute; - right: 0; - top: 0; -} #grav-login .delimiter { display: block; @@ -132,86 +60,6 @@ right: 0; } -#grav-login .form-oauth { - position: relative; -} - -#grav-login .oauth-provider-extra { - background: #eee; - border: 4px solid #eee; - border-radius: 4px; - opacity: 0; - position: absolute; - z-index: 1; - right: -9999px; - top: 1.6rem; - - -webkit-transition: opacity 0.3s ease-in-out 0s, right 0s linear 0.3s; - -moz-transition: opacity 0.3s ease-in-out 0s, right 0s linear 0.3s; - -ms-transition: opacity 0.3s ease-in-out 0s, right 0s linear 0.3s; - -o-transition: opacity 0.3s ease-in-out 0s, right 0s linear 0.3s; - transition: opacity 0.3s ease-in-out 0s, right 0s linear 0.3s; -} - -#grav-login .oauth-provider-extra::before { - background-color: ; - border: 1em solid transparent; - border-bottom-color: #eee; - bottom: 100%; - content: " "; - display: block; - height: 0; - left: 0; - margin: 0 auto; - position: absolute; - right: 0; - width: 0; -} - -#grav-login .oauth-provider-extra .button { - border: none; - border-radius: 0; - display: inline-block; - text-align: left; - width: 100%; - color: white; - font-weight: bold; - font-size: 0.9rem; -} - -#grav-login .oauth-provider-extra i[class~="fa"] { - display: inline-block; - font-size: 2rem; - margin-right: 0.5rem; - vertical-align: middle; -} - -#grav-login .form-oauth label { - color: #1bb3e9; - cursor: pointer; - display: inline; - font-weight: inherit; - position: relative; - z-index: 2; - - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - - -#grav-login #oauth-input:checked + .oauth-provider-extra { - opacity: 1; - right: 0; - - -webkit-transition: opacity 0.3s ease-in-out 0s; - -moz-transition: opacity 0.3s ease-in-out 0s; - -ms-transition: opacity 0.3s ease-in-out 0s; - -o-transition: opacity 0.3s ease-in-out 0s; - transition: opacity 0.3s ease-in-out 0s; -} - #grav-login .rememberme { display: inline-block; float: left; From a2670fb5f5fe9c58656a9302784eeac260321491 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 9 Feb 2016 21:46:17 +0100 Subject: [PATCH 12/68] Set Session timeout to 1 week minimum in "Remember me". Add help. Remove previous section header. --- blueprints.yaml | 7 ++++--- classes/Controller.php | 1 + languages.yaml | 4 +--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index 21d0b8d..75f6d06 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -81,7 +81,7 @@ form: rememberme: type: section - title: PLUGIN_LOGIN.SESSION + title: PLUGIN_LOGIN.REMEMBER_ME fields: rememberme.enabled: @@ -98,11 +98,12 @@ form: rememberme.timeout: type: text size: small + default: 604800 label: PLUGIN_ADMIN.TIMEOUT - help: PLUGIN_ADMIN.TIMEOUT_HELP + help: PLUGIN_LOGIN.TIMEOUT_HELP validate: type: number - min: 1 + min: 604800 rememberme.name: type: text diff --git a/classes/Controller.php b/classes/Controller.php index 01b4e6a..1ee43d2 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -386,6 +386,7 @@ public function rememberMe($var = null) if ($var !== null) { $this->rememberMe = $var; } + if (!$this->rememberMe) { /** @var Config $config */ $config = $this->grav['config']; diff --git a/languages.yaml b/languages.yaml index ed4fcff..afec4ba 100644 --- a/languages.yaml +++ b/languages.yaml @@ -9,7 +9,6 @@ en: BTN_LOGOUT: Logout BTN_FORGOT: Forgot BTN_REGISTER: Register - SESSION: "“Remember Me”-Session" REMEMBER_ME: Remember Me REMEMBER_ME_HELP: "Sets a persistent cookie on your browser to allow persistent-login authentication between sessions." REMEMBER_ME_STOLEN_COOKIE: "Someone else has used your login information to access this page! All sessions were logged out. Please log in with your credentials and check your data." @@ -64,6 +63,7 @@ en: OPTIONS: Options EMAIL_VALIDATION_MESSAGE: "Must be a valid email address" PASSWORD_VALIDATION_MESSAGE: "Password must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters" + TIMEOUT_HELP: "Sets the session timeout in seconds when Remember Me is enabled and checked by the user. Minimum is 604800 which means 1 week" fr: PLUGIN_LOGIN: @@ -76,7 +76,6 @@ fr: BTN_LOGOUT: Déconnexion BTN_FORGOT: Mot de passe oublié BTN_REGISTER: S'enregister - SESSION: "“Se souvenir de moi” - Session" REMEMBER_ME: Se souvenir de moi REMEMBER_ME_HELP: "Définit un cookie sur votre navigateur pour permettant l'authentification par connexion persistante entre les sessions." REMEMBER_ME_STOLEN_COOKIE: "Quelqu'un d'autre a utilisé vos informations de connexion pour accéder à cette page ! Toutes les sessions ont été déconnectées. Veuillez vous connecter avec vos identifiants et vérifier vos données." @@ -186,7 +185,6 @@ hu: BTN_LOGOUT: Kilépés BTN_FORGOT: Elfelejtettem BTN_REGISTER: Regisztráció - SESSION: "Munkamenet Megjegyzése" REMEMBER_ME: Jegyezz Meg REMEMBER_ME_HELP: "Elhelyezünk egy hosszú lejáratú sütit a böngésződben, hogy belépve maradhass két munkamenet között." REMEMBER_ME_STOLEN_COOKIE: "Valaki a belépési adataid felhasználásával látogatta meg ezt az oldalt! Minden munkamenetet kiléptettünk. Kérlek, jelentkezz be ismét és ellenőrizd az adataidat." From 163786519a43bf27e81e15c9c44e79928103af7d Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 9 Feb 2016 23:13:00 +0100 Subject: [PATCH 13/68] Add a proper 'Access levels' config section for Login. Separate user registration process to own method --- blueprints.yaml | 24 ++++++++ languages.yaml | 2 + login.php | 157 +++++++++++++++++++++++++++--------------------- 3 files changed, 114 insertions(+), 69 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index 75f6d06..c61c550 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -160,6 +160,30 @@ form: placeholder_key: PLUGIN_LOGIN.ADDITIONAL_PARAM_KEY placeholder_value: PLUGIN_LOGIN.ADDITIONAL_PARAM_VALUE + access_levels: + title: PLUGIN_ADMIN.ACCESS_LEVELS + type: section + security: admin.super + + fields: + user_registration.groups: + type: selectize + size: large + label: PLUGIN_ADMIN.GROUPS + '@data-options': '\Grav\User\Groups::groups' + classes: fancy + help: PLUGIN_LOGIN.GROUPS_HELP + validate: + type: commalist + + user_registration.access.site: + type: array + label: PLUGIN_ADMIN.SITE_ACCESS + help: PLUGIN_LOGIN.SITE_ACCESS_HELP + multiple: false + validate: + type: array + options: type: section title: PLUGIN_LOGIN.OPTIONS diff --git a/languages.yaml b/languages.yaml index afec4ba..b032ed1 100644 --- a/languages.yaml +++ b/languages.yaml @@ -64,6 +64,8 @@ en: EMAIL_VALIDATION_MESSAGE: "Must be a valid email address" PASSWORD_VALIDATION_MESSAGE: "Password must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters" TIMEOUT_HELP: "Sets the session timeout in seconds when Remember Me is enabled and checked by the user. Minimum is 604800 which means 1 week" + GROUPS_HELP: "List of groups the new registered user will be part of, if any" + SITE_ACCESS_HELP: "List of site access levels the new registered user will have. Example: `login` -> `true` " fr: PLUGIN_LOGIN: diff --git a/login.php b/login.php index 73b3b3b..b9a2619 100644 --- a/login.php +++ b/login.php @@ -13,6 +13,7 @@ use Grav\Common\Uri; use Grav\Plugin\Login\Login; use Grav\Plugin\Login\Controller; +use Grav\Plugin\Form; use RocketTheme\Toolbox\Event\Event; use RocketTheme\Toolbox\Session\Message; @@ -506,97 +507,115 @@ public function onTwigSiteVariables() } /** - * Process a registration form. Handles the following actions: - * - * - register_user: registers a user + * Process the user registration, triggered by a registration form * - * @param Event $event + * @param Form $form */ - public function onFormProcessed(Event $event) + private function processUserRegistration($form) { - $form = $event['form']; - $action = $event['action']; - $params = $event['params']; + if (!$this->config->get('plugins.login.enabled')) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.PLUGIN_LOGIN_DISABLED')); + } - switch ($action) { + if (!$this->config->get('plugins.login.user_registration.enabled')) { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_REGISTRATION_DISABLED')); + } - case 'register_user': + $data = []; + $username = $form->value('username'); + $data['username'] = $username; - if (!$this->config->get('plugins.login.enabled')) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.PLUGIN_LOGIN_DISABLED')); - } + if (file_exists($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT))) { + $this->grav->fireEvent('onFormValidationError', new Event([ + 'form' => $form, + 'message' => $this->grav['language']->translate([ + 'PLUGIN_LOGIN.USERNAME_NOT_AVAILABLE', + $username + ]) + ])); + $event->stopPropagation(); - if (!$this->config->get('plugins.login.user_registration.enabled')) { - throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_REGISTRATION_DISABLED')); - } + return; + } - $data = []; - $username = $form->value('username'); - $data['username'] = $username; + if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', + false) + ) { + if ($form->value('password1') != $form->value('password2')) { + $this->grav->fireEvent('onFormValidationError', new Event([ + 'form' => $form, + 'message' => $this->grav['language']->translate('PLUGIN_LOGIN.PASSWORDS_DO_NOT_MATCH') + ])); + $event->stopPropagation(); - if (file_exists($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT))) { - $this->grav->fireEvent('onFormValidationError', new Event([ - 'form' => $form, - 'message' => $this->grav['language']->translate([ - 'PLUGIN_LOGIN.USERNAME_NOT_AVAILABLE', - $username - ]) - ])); - $event->stopPropagation(); + return; + } + $data['password'] = $form->value('password1'); + } - return; - } + $fields = $this->config->get('plugins.login.user_registration.fields', []); - if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', - false) - ) { - if ($form->value('password1') != $form->value('password2')) { - $this->grav->fireEvent('onFormValidationError', new Event([ - 'form' => $form, - 'message' => $this->grav['language']->translate('PLUGIN_LOGIN.PASSWORDS_DO_NOT_MATCH') - ])); - $event->stopPropagation(); + foreach ($fields as $field) { + // Process value of field if set in the page process.register_user + $default_values = $this->config->get('plugins.login.user_registration.default_values'); + if ($default_values) { + foreach ($default_values as $key => $param) { + $values = explode(',', $param); - return; + if ($key == $field) { + $data[$field] = $values; } - $data['password'] = $form->value('password1'); } + } - $fields = $this->config->get('plugins.login.user_registration.fields', []); + if (!isset($data[$field]) && $form->value($field)) { + $data[$field] = $form->value($field); + } + } - foreach ($fields as $field) { - // Process value of field if set in the page process.register_user - $default_values = $this->config->get('plugins.login.user_registration.default_values'); - if ($default_values) { - foreach ($default_values as $key => $param) { - $values = explode(',', $param); - if ($key == $field) { - $data[$field] = $values; - } - } - } + $groups = $this->config->get('plugins.login.user_registration.groups', []); - if (!isset($data[$field]) && $form->value($field)) { - $data[$field] = $form->value($field); - } - } + if (count($groups) > 0) { + $data['groups'] = $groups; + } - if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', - false) - ) { - unset($data['password1']); - unset($data['password2']); - } + $access = $this->config->get('plugins.login.user_registration.access.site', []); + if (count($access) > 0) { + $data['access']['site'] = $access; + } + if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', + false) + ) { + unset($data['password1']); + unset($data['password2']); + } - if ($this->config->get('plugins.login.user_registration.options.set_user_disabled', false)) { - $data['state'] = 'disabled'; - } else { - $data['state'] = 'enabled'; - } + if ($this->config->get('plugins.login.user_registration.options.set_user_disabled', false)) { + $data['state'] = 'disabled'; + } else { + $data['state'] = 'enabled'; + } + + $this->login->register($data); + } + + /** + * Process a registration form. Handles the following actions: + * + * - register_user: registers a user + * + * @param Event $event + */ + public function onFormProcessed(Event $event) + { + $form = $event['form']; + $action = $event['action']; - $this->login->register($data); + switch ($action) { + case 'register_user': + $this->processUserRegistration($form); break; } } From 5b52363d5ddac7034512815d506ca32da6ece3e8 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 10:29:44 +0100 Subject: [PATCH 14/68] Return $user in Login::register(). Process redirect in calling method. Use --- classes/Login.php | 31 ++++++++++++++----------------- login.php | 30 +++++++++++++++++------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/classes/Login.php b/classes/Login.php index 06a8131..7330f39 100644 --- a/classes/Login.php +++ b/classes/Login.php @@ -138,10 +138,22 @@ public function authorize($action = 'admin.login') * * @param array $data * - * @return bool + * @return User */ public function register($data) { + //Add new user ACL settings + $groups = $this->config->get('plugins.login.user_registration.groups', []); + + if (count($groups) > 0) { + $data['groups'] = $groups; + } + + $access = $this->config->get('plugins.login.user_registration.access.site', []); + if (count($access) > 0) { + $data['access']['site'] = $access; + } + // Create user object and save it $user = new User($data); $username = $data['username']; @@ -154,7 +166,6 @@ public function register($data) if ($data['state'] == 'enabled' && $this->config->get('plugins.login.user_registration.options.login_after_registration', false) ) { - //Login user $this->grav['session']->user = $user; unset($this->grav['user']); @@ -162,21 +173,7 @@ public function register($data) $user->authenticated = $user->authorize('site.login'); } - if ($this->config->get('plugins.login.user_registration.options.send_activation_email', false)) { - $this->sendActivationEmail($user); - } else { - if ($this->config->get('plugins.login.user_registration.options.send_welcome_email', false)) { - $this->sendWelcomeEmail($user); - } - if ($this->config->get('plugins.login.user_registration.options.send_notification_email', false)) { - $this->sendNotificationEmail($user); - } - } - - $redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration', false); - if ($redirect) { - $this->grav->redirect($redirect); - } + return $user; } diff --git a/login.php b/login.php index b9a2619..06372aa 100644 --- a/login.php +++ b/login.php @@ -573,18 +573,6 @@ private function processUserRegistration($form) } } - - $groups = $this->config->get('plugins.login.user_registration.groups', []); - - if (count($groups) > 0) { - $data['groups'] = $groups; - } - - $access = $this->config->get('plugins.login.user_registration.access.site', []); - if (count($access) > 0) { - $data['access']['site'] = $access; - } - if ($this->config->get('plugins.login.user_registration.options.validate_password1_and_password2', false) ) { @@ -598,7 +586,23 @@ private function processUserRegistration($form) $data['state'] = 'enabled'; } - $this->login->register($data); + $user = $this->login->register($data); + + if ($this->config->get('plugins.login.user_registration.options.send_activation_email', false)) { + $this->sendActivationEmail($user); + } else { + if ($this->config->get('plugins.login.user_registration.options.send_welcome_email', false)) { + $this->sendWelcomeEmail($user); + } + if ($this->config->get('plugins.login.user_registration.options.send_notification_email', false)) { + $this->sendNotificationEmail($user); + } + } + + $redirect = $this->config->get('plugins.login.user_registration.redirect_after_registration', false); + if ($redirect) { + $this->grav->redirect($redirect); + } } /** From b1927092d3448c3807cfff1d26fa728be492e67f Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 10:29:54 +0100 Subject: [PATCH 15/68] Fixed login.yaml with new params --- login.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/login.yaml b/login.yaml index 5c26e44..13281c7 100644 --- a/login.yaml +++ b/login.yaml @@ -17,11 +17,10 @@ user_registration: - 'email' - 'fullname' - 'title' - - 'access' - - 'state' - additional_params: - access: 'site.login' + access: + site: + login: 'true' options: validate_password1_and_password2: true From 666be5cb679aee137b0acb8a68b54b2975585eea Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 11:33:50 +0100 Subject: [PATCH 16/68] Additional check --- classes/Login.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Login.php b/classes/Login.php index 7330f39..668d5c9 100644 --- a/classes/Login.php +++ b/classes/Login.php @@ -159,12 +159,12 @@ public function register($data) $username = $data['username']; $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $user->file($file); $user->save(); $user = User::load($username); - if ($data['state'] == 'enabled' && $this->config->get('plugins.login.user_registration.options.login_after_registration', - false) + if (isset($data['state']) && $data['state'] == 'enabled' && $this->config->get('plugins.login.user_registration.options.login_after_registration', false) ) { //Login user $this->grav['session']->user = $user; From 49cc7696943a6955c8770a25207b5fc4f71202da Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 14:34:25 +0100 Subject: [PATCH 17/68] Reorganize a bit the code --- classes/Controller.php | 6 ++++++ classes/Login.php | 8 +++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/classes/Controller.php b/classes/Controller.php index 1ee43d2..653f960 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -5,6 +5,7 @@ use Grav\Common\Config\Config; use Grav\Common\Grav; use Grav\Plugin\Login\RememberMe; +use Grav\Plugin\Login\Login; use Grav\Common\Language\Language; use Grav\Common\User\User; use Grav\Common\Utils; @@ -54,6 +55,11 @@ class Controller */ protected $rememberMe; + /** + * @var Login + */ + protected $login; + /** * @param Grav $grav * @param string $action diff --git a/classes/Login.php b/classes/Login.php index 668d5c9..55f1a17 100644 --- a/classes/Login.php +++ b/classes/Login.php @@ -154,18 +154,16 @@ public function register($data) $data['access']['site'] = $access; } - // Create user object and save it - $user = new User($data); $username = $data['username']; $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + // Create user object and save it + $user = new User($data); $user->file($file); $user->save(); - $user = User::load($username); - if (isset($data['state']) && $data['state'] == 'enabled' && $this->config->get('plugins.login.user_registration.options.login_after_registration', false) - ) { + if (isset($data['state']) && $data['state'] == 'enabled' && $this->config->get('plugins.login.user_registration.options.login_after_registration', false)) { //Login user $this->grav['session']->user = $user; unset($this->grav['user']); From 00f1201c9432f8b5f7a57e44662666ece9e9fb5d Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 14:34:32 +0100 Subject: [PATCH 18/68] Allow user newly registered to correctly have the access levels --- login.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/login.php b/login.php index 06372aa..7dd09f1 100644 --- a/login.php +++ b/login.php @@ -389,6 +389,9 @@ public function authorizePage() { /** @var User $user */ $user = $this->grav['user']; + if (!$user->get('access')) { + $user = User::load($user->get('username')); + } /** @var Page $page */ $page = $this->grav['page']; From db91068d73d90be2aa73c936463828ef527b728e Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 14:41:36 +0100 Subject: [PATCH 19/68] Validation for password reset. Improve form. --- pages/reset.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pages/reset.md b/pages/reset.md index 35285a2..c410367 100644 --- a/pages/reset.md +++ b/pages/reset.md @@ -4,17 +4,26 @@ title: Reset password form: fields: - name: username - type: text + type: hidden id: username placeholder: Username readonly: true + - name: password type: password id: password placeholder: Password autofocus: true + validate: + required: true + message: PLUGIN_LOGIN.PASSWORD_VALIDATION_MESSAGE + pattern: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' + - name: token type: hidden --- -# Password Reset \ No newline at end of file +# Password Reset + +### Username: {{uri.param('user')}} + From bfd84bf6efeb0d9e91d53d061a1594405c10c165 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 14:48:52 +0100 Subject: [PATCH 20/68] Fix forgot form --- pages/forgot.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pages/forgot.md b/pages/forgot.md index 8eb5e1e..53c2f30 100644 --- a/pages/forgot.md +++ b/pages/forgot.md @@ -8,6 +8,10 @@ form: id: username placeholder: Username autofocus: true + validate: + required: true + message: PLUGIN_LOGIN.USERNAME_NOT_VALID + pattern: '^[a-z0-9_-]{3,16}$' --- From 30fa16c33ac060e31c2dffc567d58c9159871792 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 17:27:33 +0100 Subject: [PATCH 21/68] Fix redirects --- blueprints.yaml | 2 +- classes/Controller.php | 12 +++++------- login.yaml | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index c61c550..a46806f 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -61,7 +61,7 @@ form: help: PLUGIN_LOGIN.ROUTE_HELP placeholder: "/my-custom-login" - redirect: + redirect_after_login: type: text label: PLUGIN_LOGIN.REDIRECT_AFTER_LOGIN help: PLUGIN_LOGIN.REDIRECT_AFTER_LOGIN_HELP diff --git a/classes/Controller.php b/classes/Controller.php index 653f960..ccb68a8 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -116,8 +116,11 @@ public function taskLogin() $t = $this->grav['language']; if ($this->authenticate($this->post)) { $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); - $referrer = $this->grav['uri']->referrer('/'); - $this->setRedirect($referrer); + $redirect = $this->grav['uri']->referrer('/'); + if (!$referrer) { + $redirect = $this->grav['config']->get('plugins.login.redirect_after_login'); + } + $this->setRedirect($redirect); } else { $user = $this->grav['user']; if ($user->username) { @@ -347,11 +350,6 @@ public function redirect() { if ($this->redirect) { $this->grav->redirect($this->redirect, $this->redirectCode); - } else { - $redirect = $this->grav['config']->get('plugins.login.redirect'); - if ($redirect) { - $this->grav->redirect($redirect, $this->redirectCode); - } } } diff --git a/login.yaml b/login.yaml index 13281c7..a5c5119 100644 --- a/login.yaml +++ b/login.yaml @@ -5,7 +5,7 @@ route_register: false route_activate: /activate_user route_forgot: /forgot_password route_reset: /reset_password -redirect: +redirect_after_login: parent_acl: false user_registration: From 59bcb36564e2514cd244d47dca96635b0898e527 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 18:08:02 +0100 Subject: [PATCH 22/68] Fix redirects when redirect_after_login is set. Save to session the login-protected page URL for later use --- classes/Controller.php | 7 ++++--- login.php | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/classes/Controller.php b/classes/Controller.php index ccb68a8..33e8d60 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -116,9 +116,10 @@ public function taskLogin() $t = $this->grav['language']; if ($this->authenticate($this->post)) { $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); - $redirect = $this->grav['uri']->referrer('/'); - if (!$referrer) { - $redirect = $this->grav['config']->get('plugins.login.redirect_after_login'); + + $redirect = $this->grav['config']->get('plugins.login.redirect_after_login'); + if (!$redirect) { + $redirect = $this->grav['uri']->referrer('/'); } $this->setRedirect($redirect); } else { diff --git a/login.php b/login.php index 7dd09f1..2fe0308 100644 --- a/login.php +++ b/login.php @@ -441,6 +441,8 @@ public function authorizePage() if (!$user->authenticated) { $page = new Page; + $this->grav['session']->redirect_after_login = $this->grav['uri']->path(); + // Get the admin Login page is needed, else teh default if ($this->isAdmin()) { $login_file = $this->grav['locator']->findResource("plugins://admin/pages/admin/login.md"); From 306251b390f4c28c34e9541f7537c8cae3153321 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 10 Feb 2016 19:00:05 +0100 Subject: [PATCH 23/68] Add changes to readme --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index ff6fe44..a3c7ed3 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,15 @@ These are available via GPM, and because the plugin has dependencies you just ne $ bin/gpm install login ``` +# Changes in version 2.0 (STILL TO BE RELEASED) + +The Login Plugin 2.0 has the following changes compared to 1.0: + +- OAuth has been separated to its own plugin, needs to be installed separately and configured. The users account filename format has changed too, to fix an issue that involved people with the same name on a service. +- The `redirect` option has been changed to `redirect_after_login`. +- The Remember Me session minimum length is now 1 week. +- Removed the option to login from oauth without creating the corresponding user file under `user/accounts/`. + # Creating Users You can either use the built-in CLI capabilities, or you create a user manually by creating a new YAML file in your `user/acounts` folder. From c40730f35ec1fdf8758912bc7889a9ae6d5e25a0 Mon Sep 17 00:00:00 2001 From: Vivalldi Date: Wed, 10 Feb 2016 22:07:52 -0500 Subject: [PATCH 24/68] fix button alignment --- css/login.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/css/login.css b/css/login.css index 2d26583..6b7f3c4 100644 --- a/css/login.css +++ b/css/login.css @@ -32,6 +32,10 @@ margin-bottom: 0; } +#grav-login .button { + vertical-align: middle; +} + #grav-login .delimiter { display: block; font-size: 1.6rem; From 910234b97bf676bff2ad6959082c076ce9a2a3b3 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Thu, 11 Feb 2016 20:37:29 +0100 Subject: [PATCH 25/68] Use full name if available --- templates/partials/login-status.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/partials/login-status.html.twig b/templates/partials/login-status.html.twig index 28c8f4e..546563c 100644 --- a/templates/partials/login-status.html.twig +++ b/templates/partials/login-status.html.twig @@ -1,5 +1,5 @@ From 364b756e3d08bec573748fcd7107450daae62e17 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Sun, 14 Feb 2016 14:28:20 +0100 Subject: [PATCH 26/68] Fix #59 Fix issue with with access denied --- templates/partials/login-form.html.twig | 68 +++++++++++++++---------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/templates/partials/login-form.html.twig b/templates/partials/login-form.html.twig index 84ae806..f8334d8 100644 --- a/templates/partials/login-form.html.twig +++ b/templates/partials/login-form.html.twig @@ -1,40 +1,54 @@ {% set icons = {'Microsoft': 'windows'} %}

- {{ content }} + {% if page.template == 'login' %} + {{ content }} + {% endif %} {% include 'partials/messages.html.twig' %} - - {% if grav.twig.plugins_hooked_loginPage %} - {% for label in grav.twig.plugins_hooked_loginPage %} - - {% include label %} - {% endfor %} - {% endif %} + {% if page.template == 'login' %} + + + {% if grav.twig.plugins_hooked_loginPage %} + {% for label in grav.twig.plugins_hooked_loginPage %} - {% for field in page.header.form.fields %} - {% if field.type %} -
- {% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %} -
+ {% include label %} + {% endfor %} {% endif %} - {% endfor %} -
- {% if config.plugins.login.rememberme.enabled %} -
-
- - + + {% for field in page.header.form.fields %} + {% if field.type %} +
+ {% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %}
-
- {% endif %} + {% endif %} + {% endfor %} +
+ {% if config.plugins.login.rememberme.enabled %} +
+
+ + +
+
+ {% endif %} + + {{ 'PLUGIN_LOGIN.BTN_FORGOT'|t }} + + +
- {{ 'PLUGIN_LOGIN.BTN_FORGOT'|t }} + {{ nonce_field('login-form', 'login-form-nonce') }} + + + {% else %} + + {% if grav.user.username %} +
+ Logout + {% endif %} - -
+ {% endif %} - {{ nonce_field('login-form', 'login-form-nonce') }} -
From 2bae591c3d2a5217d7b0073135bc1f717ed7461a Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Sun, 28 Feb 2016 13:29:17 +0100 Subject: [PATCH 27/68] Change form actions and logout links to be relative URLs --- templates/partials/forgot-form.html.twig | 2 +- templates/partials/login-form.html.twig | 4 ++-- templates/partials/login-status.html.twig | 2 +- templates/partials/reset-form.html.twig | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/partials/forgot-form.html.twig b/templates/partials/forgot-form.html.twig index 9389a10..24299d4 100644 --- a/templates/partials/forgot-form.html.twig +++ b/templates/partials/forgot-form.html.twig @@ -3,7 +3,7 @@ {% include 'partials/messages.html.twig' %} -
+ {% for field in page.header.form.fields %} {% if field.type %}
diff --git a/templates/partials/login-form.html.twig b/templates/partials/login-form.html.twig index f8334d8..a54b0ee 100644 --- a/templates/partials/login-form.html.twig +++ b/templates/partials/login-form.html.twig @@ -9,7 +9,7 @@ {% if page.template == 'login' %} - + {% if grav.twig.plugins_hooked_loginPage %} {% for label in grav.twig.plugins_hooked_loginPage %} @@ -46,7 +46,7 @@ {% if grav.user.username %}
- Logout + Logout {% endif %} {% endif %} diff --git a/templates/partials/login-status.html.twig b/templates/partials/login-status.html.twig index 546563c..d4ab4f2 100644 --- a/templates/partials/login-status.html.twig +++ b/templates/partials/login-status.html.twig @@ -1,5 +1,5 @@ diff --git a/templates/partials/reset-form.html.twig b/templates/partials/reset-form.html.twig index 114b301..233476f 100644 --- a/templates/partials/reset-form.html.twig +++ b/templates/partials/reset-form.html.twig @@ -3,7 +3,7 @@ {% include 'partials/messages.html.twig' %} - + {% for field in page.header.form.fields %} {% set value = attribute(grav.twig.twig_vars, field.name) is defined ? attribute(grav.twig.twig_vars, field.name) : null %} From 7295b78ecf3c7e99272364f6e53ae2da3c2e75a9 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 1 Mar 2016 15:57:51 -0700 Subject: [PATCH 28/68] fixed missing grav trait references --- cli/NewUserCommand.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cli/NewUserCommand.php b/cli/NewUserCommand.php index 1b595ef..a0e479a 100644 --- a/cli/NewUserCommand.php +++ b/cli/NewUserCommand.php @@ -4,6 +4,7 @@ use Grav\Console\ConsoleCommand; use Grav\Common\File\CompiledYamlFile; use Grav\Common\User\User; +use Grav\Common\Grav; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Helper\Helper; use Symfony\Component\Console\Question\ChoiceQuestion; @@ -207,7 +208,7 @@ protected function serve() // Create user object and save it $user = new User($data); - $file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $file = CompiledYamlFile::instance(Grav::instance()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); $user->file($file); $user->save(); @@ -239,7 +240,7 @@ protected function validate($type, $value, $extra = '') if (!preg_match('/^[a-z0-9_-]{3,16}$/', $value)) { throw new \RuntimeException('Username should be between 3 and 16 characters, including lowercase letters, numbers, underscores, and hyphens. Uppercase letters, spaces, and special characters are not allowed'); } - if (file_exists(self::getGrav()['locator']->findResource('user://accounts/' . $value . YAML_EXT))) { + if (file_exists(Grav::instance()['locator']->findResource('user://accounts/' . $value . YAML_EXT))) { throw new \RuntimeException('Username "' . $value . '" already exists, please pick another username'); } From 52c0ed596cbf82c7cbc72f46ac26ffadc34d5b25 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Thevenet Date: Sun, 6 Mar 2016 09:47:28 -0400 Subject: [PATCH 29/68] :fr: updated :fr: updated few strings still need to be translated --- languages.yaml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/languages.yaml b/languages.yaml index b032ed1..67d3699 100644 --- a/languages.yaml +++ b/languages.yaml @@ -106,16 +106,16 @@ fr: INVALID_REQUEST: "Requête invalide" USER_REGISTRATION: "Inscription de l'utilisateur" USER_REGISTRATION_ENABLED_HELP: "Activer l'inscription des utilisateurs" - VALIDATE_PASSWORD1_AND_PASSWORD2: "Validate double entered password" + VALIDATE_PASSWORD1_AND_PASSWORD2: "Valider la double saisie du mot de passe" VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Validate and compare two different fields for the passwords, named `password1` and `password2`. Enable this if you have two password fields in the registration form" SET_USER_DISABLED: "Définir l'utilisateur comme désactivé" SET_USER_DISABLED_HELP: "Best used along with the `Send activation email` email. Adds the user to Grav, but sets it as disabled" LOGIN_AFTER_REGISTRATION: "Connecte l'utilisateur après son inscription" LOGIN_AFTER_REGISTRATION_HELP: "Identifier immédiatement l'utilisateur après l'inscription. Si l'email d'activation est demandé, l'utilisateur sera connecté immédiatement après l'activation du compte" SEND_ACTIVATION_EMAIL: "Envoyer un e-mail d'activation" - SEND_ACTIVATION_EMAIL_HELP: "Sends an email to the user to activate his account. Enable the `Set the user as disabled` option when using this feature, so the user will be set as disabled and an email will be sent to activate the account" + SEND_ACTIVATION_EMAIL_HELP: "Envoyer un e-mail à l'utilisateur pour l'activation son compte. Lorsque vous utilisez cette fonction, activez l'option `Définir l'utilisateur comme désactivé` afin que l'utilisateur soit désactivé et qu'un email soit envoyé à l'utilisateur pour activer son compte." SEND_NOTIFICATION_EMAIL: "Envoyer un e-mail de notification" - SEND_NOTIFICATION_EMAIL_HELP: "Notifies the site admin that a new user has registered. The email will be sent to the `To` field in the Email Plugin configuration" + SEND_NOTIFICATION_EMAIL_HELP: "Informe l'administrateur du site qu'un nouvel utilisateur s'est enregistré. L'e-mail sera envoyé à la personne renseignée dans le champ `A` dans la configuration du plugin e-mail." SEND_WELCOME_EMAIL: "Envoyer un e-mail de bienvenue" SEND_WELCOME_EMAIL_HELP: "Envoyer un e-mail à un nouvel utilisateur enregistré." DEFAULT_VALUES: "Valeurs par défaut" @@ -132,6 +132,9 @@ fr: OPTIONS: Options EMAIL_VALIDATION_MESSAGE: "Doit-être une adresse e-mail valide" PASSWORD_VALIDATION_MESSAGE: "Le mot de passe doit-être composé d'au moins un chiffre, une majuscule et une minuscule, et au moins 8 caractères" + TIMEOUT_HELP: "Définit le délai d'expiration de la session en secondes lorsque 'Se souvenir de moi' est activé et coché par l'utilisateur. Minimum de 604800 ce qui correspond à 1 semaine." + GROUPS_HELP: "Liste des groupes auxquels le nouvel utilisateur enregistré fera partie, le cas échéant." + SITE_ACCESS_HELP: "Liste des niveaux d'accès au site attribués au nouvel utilisateur enregistré. Exemple : `login` -> `true` " hr: PLUGIN_LOGIN: From 7a08af2f97bc328bde18d5a87c13b97775313f30 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Thevenet Date: Mon, 7 Mar 2016 11:51:55 -0400 Subject: [PATCH 30/68] :fr: updated I hope at this point the :fr: is ok. at least following the :uk: version. --- languages.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/languages.yaml b/languages.yaml index 67d3699..369b151 100644 --- a/languages.yaml +++ b/languages.yaml @@ -107,15 +107,15 @@ fr: USER_REGISTRATION: "Inscription de l'utilisateur" USER_REGISTRATION_ENABLED_HELP: "Activer l'inscription des utilisateurs" VALIDATE_PASSWORD1_AND_PASSWORD2: "Valider la double saisie du mot de passe" - VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Validate and compare two different fields for the passwords, named `password1` and `password2`. Enable this if you have two password fields in the registration form" + VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Comparer et valider deux champs pour les mots de passe `Mot de passe 1` et `Mot de passe 2`. Activez cette option si vous avez deux champs de mots de passe dans le formulaire d'inscription." SET_USER_DISABLED: "Définir l'utilisateur comme désactivé" - SET_USER_DISABLED_HELP: "Best used along with the `Send activation email` email. Adds the user to Grav, but sets it as disabled" + SET_USER_DISABLED_HELP: "La meilleure pratique si vous utilisez l'option `Envoyer un e-mail d'activation`. Ajoute l'utilisateur à Grav, mais le défini comme étant désactivé." LOGIN_AFTER_REGISTRATION: "Connecte l'utilisateur après son inscription" - LOGIN_AFTER_REGISTRATION_HELP: "Identifier immédiatement l'utilisateur après l'inscription. Si l'email d'activation est demandé, l'utilisateur sera connecté immédiatement après l'activation du compte" + LOGIN_AFTER_REGISTRATION_HELP: "Identifier immédiatement l'utilisateur après l'inscription. Si l'e-mail d'activation est demandé, l'utilisateur sera connecté immédiatement après l'activation du compte." SEND_ACTIVATION_EMAIL: "Envoyer un e-mail d'activation" - SEND_ACTIVATION_EMAIL_HELP: "Envoyer un e-mail à l'utilisateur pour l'activation son compte. Lorsque vous utilisez cette fonction, activez l'option `Définir l'utilisateur comme désactivé` afin que l'utilisateur soit désactivé et qu'un email soit envoyé à l'utilisateur pour activer son compte." + SEND_ACTIVATION_EMAIL_HELP: "Envoyer un e-mail à l'utilisateur pour l'activation son compte. Lorsque vous utilisez cette fonction, activez l'option `Définir l'utilisateur comme désactivé` afin que l'utilisateur soit désactivé et qu'un email lui soit envoyé pour activer son compte." SEND_NOTIFICATION_EMAIL: "Envoyer un e-mail de notification" - SEND_NOTIFICATION_EMAIL_HELP: "Informe l'administrateur du site qu'un nouvel utilisateur s'est enregistré. L'e-mail sera envoyé à la personne renseignée dans le champ `A` dans la configuration du plugin e-mail." + SEND_NOTIFICATION_EMAIL_HELP: "Informe l'administrateur du site qu'un nouvel utilisateur s'est enregistré. L'e-mail sera envoyé à la personne renseignée dans le champ `À` dans la configuration du plugin e-mail." SEND_WELCOME_EMAIL: "Envoyer un e-mail de bienvenue" SEND_WELCOME_EMAIL_HELP: "Envoyer un e-mail à un nouvel utilisateur enregistré." DEFAULT_VALUES: "Valeurs par défaut" From 127ec5d03a2014eecf4fddc5d90618ced63bc638 Mon Sep 17 00:00:00 2001 From: Henri Date: Fri, 11 Mar 2016 13:31:55 +0100 Subject: [PATCH 31/68] Added german language --- languages.yaml | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/languages.yaml b/languages.yaml index 369b151..fe80480 100644 --- a/languages.yaml +++ b/languages.yaml @@ -203,3 +203,50 @@ hu: USERNAME_NOT_AVAILABLE: "%s nevű felhasználó már létezik, kérlek válassz más felhasználónevet" PASSWORD_NOT_VALID: "A jelszónak tartalmaznia kell legalább egy számot, egy kisbetűt és egy nagybetűt, valamint legalább 8 karakter hosszú kell, hogy legyen" PASSWORDS_DO_NOT_MATCH: "A két jelszó nem egyezik meg. Győzödj meg róla, hogy azonos legyen a kettő" + +de: + PLUGIN_LOGIN: + USERNAME: Nutzername + PASSWORD: Passwort + ACCESS_DENIED: Zugang verweigert + LOGIN_FAILED: Login fehlgeschlagen... + LOGIN_SUCCESSFUL: Du wurdest erfolgreich eingeloggt. + BTN_LOGIN: Einlogen + BTN_LOGOUT: Ausloggen + BTN_FORGOT: Vergessen + BTN_REGISTER: Registrieren + REMEMBER_ME: Angemeldet bleiben + REMEMBER_ME_HELP: "Speichert einen Cookie im Browser, welcher eine fortwährende Anmeldung sicherstellt." + BUILTIN_CSS: "Nutze das integrierte CSS" + BUILTIN_CSS_HELP: "Nutze das CSS, welches vom Admin Plugin bereitgestellt werden" + ROUTE: "Anmeldepfad" + ROUTE_REGISTER: "Registrierungspfad" + USERNAME_NOT_AVAILABLE: "Der Nutzername %s existiert bereits, bitte wähle einen Anderen" + EMAIL_NOT_CONFIGURED: "E-Mail ist nicht konfiguriert" + USER_NEEDS_EMAIL_FIELD: "Der Nutzer benötigt ein E-Mail Feld" + EMAIL_SENDING_FAILURE: "Ein Fehler ist beim senden der E-Mail aufgetreten" + ACTIVATION_EMAIL_SUBJECT: "Aktiviere dein Account auf %s" + ACTIVATION_EMAIL_BODY: "Hi %s, click %s to activate your account on %s" + WELCOME_EMAIL_SUBJECT: "Willkommen zu %s" + WELCOME_EMAIL_BODY: "Hi %s, willkommen zu %s!" + NOTIFICATION_EMAIL_SUBJECT: "Neuer Nutzer auf %s" + NOTIFICATION_EMAIL_BODY: "Hi, ein neuer Nutzer hat sich auf %s registriert. Nutzername: %s, E-Mail: %s" + EMAIL_FOOTER: "GetGrav.org" + ACTIVATION_LINK_EXPIRED: "Aktivierungslink ist abgelaufen" + USER_ACTIVATED_SUCCESSFULLY: "Nutzer erfolgreich aktiviert" + INVALID_REQUEST: "Ungültige Anfrage" + USER_REGISTRATION: "Nutzer Registrierung" + USER_REGISTRATION_ENABLED_HELP: "Aktiviere die Nutzer Registrierung" + VALIDATE_PASSWORD1_AND_PASSWORD2: "Überprüfe das doppelt eingegebene Passwort" + SEND_ACTIVATION_EMAIL: "Aktivierungs E-Mail senden" + SEND_NOTIFICATION_EMAIL: "Benachtichtigungs E-Mail senden" + SEND_WELCOME_EMAIL: "Sende eine Willkommens E-Mail" + DEFAULT_VALUES: "Standard Werte" + ADDITIONAL_PARAM_KEY: "Parameter" + ADDITIONAL_PARAM_VALUE: "Wert" + REGISTRATION_FIELDS: "Registrierungsfelder" + REGISTRATION_FIELD_KEY: "Feldname" + REDIRECT_AFTER_LOGIN: "Umleitung nach Login" + REDIRECT_AFTER_REGISTRATION: "Umleitung nach Registrierung" + OPTIONS: Optionen + EMAIL_VALIDATION_MESSAGE: "Muss eine gültige E-Mail Adresse sein" From 1671caf5fa7bf1f689712d999873a840465e74a6 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 15 Mar 2016 12:04:10 -0600 Subject: [PATCH 32/68] Changed tabs to use subtle style --- blueprints.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/blueprints.yaml b/blueprints.yaml index a46806f..fc87005 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -23,6 +23,7 @@ form: tabs: type: tabs active: 1 + class: subtle fields: login: From 5762cabacbd32bf9f6ab58a752462c64e13b6e98 Mon Sep 17 00:00:00 2001 From: Oliver Stapelfeldt Date: Mon, 21 Mar 2016 09:44:59 +0100 Subject: [PATCH 33/68] Update languages.yaml --- languages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.yaml b/languages.yaml index fe80480..7504ed2 100644 --- a/languages.yaml +++ b/languages.yaml @@ -211,7 +211,7 @@ de: ACCESS_DENIED: Zugang verweigert LOGIN_FAILED: Login fehlgeschlagen... LOGIN_SUCCESSFUL: Du wurdest erfolgreich eingeloggt. - BTN_LOGIN: Einlogen + BTN_LOGIN: Einloggen BTN_LOGOUT: Ausloggen BTN_FORGOT: Vergessen BTN_REGISTER: Registrieren From 3ee793b82858adb5d52d3fa5665a27a39d44d85e Mon Sep 17 00:00:00 2001 From: Oliver Stapelfeldt Date: Wed, 23 Mar 2016 15:41:09 +0100 Subject: [PATCH 34/68] Update languages.yaml --- languages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.yaml b/languages.yaml index 7504ed2..baac462 100644 --- a/languages.yaml +++ b/languages.yaml @@ -206,7 +206,7 @@ hu: de: PLUGIN_LOGIN: - USERNAME: Nutzername + USERNAME: Benutzername PASSWORD: Passwort ACCESS_DENIED: Zugang verweigert LOGIN_FAILED: Login fehlgeschlagen... From a8dba4438eec50e19e08a8bda9503d06f3cfd0f5 Mon Sep 17 00:00:00 2001 From: Oliver Stapelfeldt Date: Wed, 23 Mar 2016 15:56:53 +0100 Subject: [PATCH 35/68] Update languages.yaml --- languages.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages.yaml b/languages.yaml index baac462..d7d7dae 100644 --- a/languages.yaml +++ b/languages.yaml @@ -211,9 +211,9 @@ de: ACCESS_DENIED: Zugang verweigert LOGIN_FAILED: Login fehlgeschlagen... LOGIN_SUCCESSFUL: Du wurdest erfolgreich eingeloggt. - BTN_LOGIN: Einloggen + BTN_LOGIN: Anmelden BTN_LOGOUT: Ausloggen - BTN_FORGOT: Vergessen + BTN_FORGOT: Passwort vergessen BTN_REGISTER: Registrieren REMEMBER_ME: Angemeldet bleiben REMEMBER_ME_HELP: "Speichert einen Cookie im Browser, welcher eine fortwährende Anmeldung sicherstellt." From 76ec8d283e9d6b0cc2c31c751a4e3ba66f5389d8 Mon Sep 17 00:00:00 2001 From: Oliver Stapelfeldt Date: Fri, 25 Mar 2016 09:45:58 +0100 Subject: [PATCH 36/68] Update languages.yaml --- languages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/languages.yaml b/languages.yaml index d7d7dae..f42badb 100644 --- a/languages.yaml +++ b/languages.yaml @@ -213,7 +213,7 @@ de: LOGIN_SUCCESSFUL: Du wurdest erfolgreich eingeloggt. BTN_LOGIN: Anmelden BTN_LOGOUT: Ausloggen - BTN_FORGOT: Passwort vergessen + BTN_FORGOT: Vergessen BTN_REGISTER: Registrieren REMEMBER_ME: Angemeldet bleiben REMEMBER_ME_HELP: "Speichert einen Cookie im Browser, welcher eine fortwährende Anmeldung sicherstellt." From 20bf0528c40c87cf7021c7d3330de2092d80b3cb Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Sat, 9 Apr 2016 19:40:51 -0400 Subject: [PATCH 37/68] Fixes #68 --- classes/Controller.php | 24 ++++++++++++------------ classes/Login.php | 4 ++-- languages.yaml | 12 ++++++++++++ templates/partials/forgot-form.html.twig | 2 +- templates/partials/reset-form.html.twig | 2 +- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/classes/Controller.php b/classes/Controller.php index 01b4e6a..caaed4a 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -164,21 +164,21 @@ protected function taskForgot() $messages = $this->grav['messages']; if (!isset($this->grav['Email'])) { - $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); $this->setRedirect('/'); return true; } if (!$user || !$user->exists()) { - $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error'); + $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error'); $this->setRedirect('/forgot'); return true; } if (empty($user->email)) { - $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), + $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), 'error'); $this->setRedirect('/forgot'); @@ -200,7 +200,7 @@ protected function taskForgot() $from = $this->grav['config']->get('plugins.email.from'); if (empty($from)) { - $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); $this->setRedirect('/forgot'); return true; @@ -208,15 +208,15 @@ protected function taskForgot() $to = $user->email; - $subject = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_SUBJECT', $sitename]); - $content = $language->translate(['PLUGIN_ADMIN.FORGOT_EMAIL_BODY', $fullname, $reset_link, $author, $sitename]); + $subject = $language->translate(['PLUGIN_LOGIN.FORGOT_EMAIL_SUBJECT', $sitename]); + $content = $language->translate(['PLUGIN_LOGIN.FORGOT_EMAIL_BODY', $fullname, $reset_link, $author, $sitename]); $sent = LoginUtils::sendEmail($subject, $content, $to); if ($sent < 1) { - $messages->add($language->translate('PLUGIN_ADMIN.FORGOT_FAILED_TO_EMAIL'), 'error'); + $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_FAILED_TO_EMAIL'), 'error'); } else { - $messages->add($language->translate(['PLUGIN_ADMIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL', $to]), 'info'); + $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL', $to]), 'info'); } $this->setRedirect('/'); @@ -246,7 +246,7 @@ public function taskReset() if ($good_token === $token) { if (time() > $expire) { - $messages->add($language->translate('PLUGIN_ADMIN.RESET_LINK_EXPIRED'), 'error'); + $messages->add($language->translate('PLUGIN_LOGIN.RESET_LINK_EXPIRED'), 'error'); $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); return true; @@ -260,14 +260,14 @@ public function taskReset() $user->filter(); $user->save(); - $messages->add($language->translate('PLUGIN_ADMIN.RESET_PASSWORD_RESET'), 'info'); + $messages->add($language->translate('PLUGIN_LOGIN.RESET_PASSWORD_RESET'), 'info'); $this->grav->redirect('/'); return true; } } - $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); + $messages->add($language->translate('PLUGIN_LOGIN.RESET_INVALID_LINK'), 'error'); $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); return true; @@ -277,7 +277,7 @@ public function taskReset() $token = $this->grav['uri']->param('token'); if (empty($user) || empty($token)) { - $messages->add($language->translate('PLUGIN_ADMIN.RESET_INVALID_LINK'), 'error'); + $messages->add($language->translate('PLUGIN_LOGIN.RESET_INVALID_LINK'), 'error'); $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot')); return true; diff --git a/classes/Login.php b/classes/Login.php index 06a8131..3b288d0 100644 --- a/classes/Login.php +++ b/classes/Login.php @@ -101,7 +101,7 @@ public function authenticate($form) /** @var Grav $grav */ $grav = $this->grav; - $this->setMessage($this->grav['language']->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN', + $this->setMessage($this->grav['language']->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL', [$this->user->language]), 'info'); $redirect_route = $this->uri->route(); @@ -285,4 +285,4 @@ protected function sendActivationEmail($user) return true; } -} \ No newline at end of file +} diff --git a/languages.yaml b/languages.yaml index ed4fcff..c8b9457 100644 --- a/languages.yaml +++ b/languages.yaml @@ -9,6 +9,18 @@ en: BTN_LOGOUT: Logout BTN_FORGOT: Forgot BTN_REGISTER: Register + BTN_RESET: "Reset Password" + BTN_SEND_INSTRUCTIONS: "Send Reset Instructions" + RESET_LINK_EXPIRED: "Reset link has expired, please try again" + RESET_PASSWORD_RESET: "Password has been reset" + RESET_INVALID_LINK: "Invalid reset link used, please try again" + FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL: "Instructions to reset your password have been sent via email to %s" + FORGOT_FAILED_TO_EMAIL: "Failed to email instructions, please try again later" + FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL: "Cannot reset password for %s, no email address is set" + FORGOT_USERNAME_DOES_NOT_EXIST: "User with username %s does not exist" + FORGOT_EMAIL_NOT_CONFIGURED: "Cannot reset password. This site is not configured to send emails" + FORGOT_EMAIL_SUBJECT: "%s Password Reset Request" + FORGOT_EMAIL_BODY: "

Password Reset

Dear %1$s,

A request was made on %4$s to reset your password.


Click this to reset your password

Alternatively, copy the following URL into your browser's address bar:

%2$s


Kind regards,

%3$s

" SESSION: "“Remember Me”-Session" REMEMBER_ME: Remember Me REMEMBER_ME_HELP: "Sets a persistent cookie on your browser to allow persistent-login authentication between sessions." diff --git a/templates/partials/forgot-form.html.twig b/templates/partials/forgot-form.html.twig index 9389a10..e74826e 100644 --- a/templates/partials/forgot-form.html.twig +++ b/templates/partials/forgot-form.html.twig @@ -12,7 +12,7 @@ {% endif %} {% endfor %}
- +
{{ nonce_field('forgot-form', 'forgot-form-nonce') }} diff --git a/templates/partials/reset-form.html.twig b/templates/partials/reset-form.html.twig index 114b301..cc72af3 100644 --- a/templates/partials/reset-form.html.twig +++ b/templates/partials/reset-form.html.twig @@ -14,7 +14,7 @@ {% endif %} {% endfor %}
- +
{{ nonce_field('reset-form', 'reset-form-nonce') }} From ac7d05590d1ec6f95502ccab9cb96be41922589e Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 20 Apr 2016 21:15:50 +0200 Subject: [PATCH 38/68] Code hint --- classes/Controller.php | 1 + 1 file changed, 1 insertion(+) diff --git a/classes/Controller.php b/classes/Controller.php index a841b54..9c6324b 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -113,6 +113,7 @@ public function execute() */ public function taskLogin() { + /** @var Language $t */ $t = $this->grav['language']; if ($this->authenticate($this->post)) { $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL')); From 9c4be2dcef348caad9b174811be23c2fb7015b95 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 20 Apr 2016 21:16:27 +0200 Subject: [PATCH 39/68] Set minimum "remember me" timeout to 1 instead of 604800 as previously committed but unreleased yet. Use 604800 (1 week) as default, as the current default is too low --- blueprints.yaml | 2 +- login.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index fc87005..ca16466 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -104,7 +104,7 @@ form: help: PLUGIN_LOGIN.TIMEOUT_HELP validate: type: number - min: 604800 + min: 1 rememberme.name: type: text diff --git a/login.yaml b/login.yaml index a5c5119..baff264 100644 --- a/login.yaml +++ b/login.yaml @@ -32,5 +32,5 @@ user_registration: rememberme: enabled: true - timeout: 1800 # Timeout in seconds + timeout: 604800 # Timeout in seconds. Defaults to 1 week name: grav-rememberme # Name prefix of the session cookie \ No newline at end of file From cb926d84cba1d8b9b14c0c7b6aea15d41abc99c4 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 20 Apr 2016 21:39:24 +0200 Subject: [PATCH 40/68] Update changelog --- CHANGELOG.md | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a8d546..284e673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,144 @@ +# v2.0.0-beta.1 +## 04/20/2016 + +1. [](#new) + * Introduce a more flexible Login plugin architecture, which allows separate authentication plugins to hook into the Login events. Separated OAuth to its own plugin. + * OAuth has been separated to its own plugin, needs to be installed separately and configured. The users account filename format has changed too, to fix an issue that involved people with the same name on a service. + * The `redirect` option has been changed to `redirect_after_login`. Make sure you update your configuration file. +1. [](#improved) + * Add a proper 'Access levels' config section for Login. + * Various underlying improvements + * Updated french, added german +1. [](#bugfix) + * Make username field autofocus + * Add validation to the password reset form + * Fixed an issue that allowed a user logged in, without access to the actual permissions set to view a page, to see its content, and the login form again even if already logged in. + +# v1.3.1 +## 02/05/2016 + +1. [](#new) + * Add translations for Username and Password (placeholders are not translated) +1. [](#improved) + * Improve registration, forgot, reset and login forms accessibility by setting the id attribute + * Improved french translation + * Add the correct message type when raising a form processing error +1. [](#bugfix) + * Show the correct error message when the user is not authorized to view a page + * Fix showing the OAuth links in the login form + +# v1.3.0 +## 01/06/2016 + +1. [](#new) + * Added a new CLI command to change a user's password + * Added a new CLI command to edit the user state +1. [](#improved) + * Improved french translation + +# v1.2.1 +## 12/18/2015 + +1. [](#new) + * Croatian translation +1. [](#improved) + * Use type `email` in registration form + * Drop manual validation in registration + +# v1.2.0 +## 12/11/2015 + +1. [](#new) + * Added account activation email upon registration + * Added forgot password functionality + * Support ACL from parent page + * Allow login immediately after account activation +1. [](#improved) + * Handle admin login page if available + * Example registration form now provided by plugin + * Better error handling of registration + * Tab-based plugin configuration + * Updated translations +1. [](#bugfix) + * Prevent failing when no default values are set + +# v1.1.0 +## 12/01/2015 + +1. [](#new) + * Support new **User Registration** +1. [](#improved) + * Use new security salt for newer and fallback otherwise + * Composer update of libraries + * Check for session existence else throw a runtime error +1. [](#bugfix) + * Fix remember-me functionality + * Check page exists so as not to fail hard + * Fix for static Inflector references #17 + + +# v1.0.1 +## 11/23/2015 + +1. [](#improved) + * Hardening cookies with user-agent and system cache key instead of deprecated system hash + * Set a custom route for login only if it's not an admin path + +# v1.0.0 +## 11/21/2015 + +1. [](#new) + * Added OAuth login support for _Facebook_, _Google_, _GitHub_ and _Twitter_ + * Added **Nonce** form security support + * Added option to "redirect after login" + * Added "remember me" functionality + * Added Hungarian translation +2. [](#improved) + * Added blueprints for Grav Admin plugin (multi-language support!) + +# v0.3.3 +## 09/11/2015 + +1. [](#improved) + * Changed authorise to authorize +1. [](#bugfix) + * Fix denied string + +# v0.3.2 +## 09/01/2015 + +1. [](#improved) + * Broke out login form into its own partial + +# v0.3.1 +## 08/31/2015 + +1. [](#improved) + * Added username field autofocus + +# v0.3.0 +## 08/24/2015 + +1. [](#new) + * Added simple CSS styling + * Added simple login status with logout +1. [](#improved) + * Improved README documentation + * More strings translated + * Updated blueprints + +# v0.2.0 +## 08/11/2015 + +1. [](#improved) + * Disable `enable` in admin + +# v0.1.0 +## 08/04/2015 + +1. [](#new) + * ChangeLog started... + # v1.3.1 ## 02/05/2016 From 22e88eac9b6e76314f4f4204820281ed1771d446 Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Wed, 20 Apr 2016 13:15:08 -0700 Subject: [PATCH 41/68] Updated version --- blueprints.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index ca16466..3bbe0f9 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,5 +1,6 @@ name: Login -version: 1.3.1 +version: 2.0.0-beta.1 +testing: true description: Enables user authentication and login screen. icon: sign-in author: @@ -254,4 +255,4 @@ form: options: 1: PLUGIN_ADMIN.YES 0: PLUGIN_ADMIN.NO - validate: \ No newline at end of file + validate: From 216c61eda8d6ab7de5355f02dfaaa5735d760014 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 2 May 2016 17:50:59 +0200 Subject: [PATCH 42/68] Fix issue in processing user registration --- classes/Login.php | 2 +- login.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) mode change 100644 => 100755 classes/Login.php mode change 100644 => 100755 login.php diff --git a/classes/Login.php b/classes/Login.php old mode 100644 new mode 100755 index 8c8caad..abedab7 --- a/classes/Login.php +++ b/classes/Login.php @@ -247,7 +247,7 @@ public function sendWelcomeEmail($user) * * @return bool True if the action was performed. */ - protected function sendActivationEmail($user) + public function sendActivationEmail($user) { if (empty($user->email)) { throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.USER_NEEDS_EMAIL_FIELD')); diff --git a/login.php b/login.php old mode 100644 new mode 100755 index 2fe0308..3469bb1 --- a/login.php +++ b/login.php @@ -516,7 +516,7 @@ public function onTwigSiteVariables() * * @param Form $form */ - private function processUserRegistration($form) + private function processUserRegistration($form, Event $event) { if (!$this->config->get('plugins.login.enabled')) { throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.PLUGIN_LOGIN_DISABLED')); @@ -594,13 +594,13 @@ private function processUserRegistration($form) $user = $this->login->register($data); if ($this->config->get('plugins.login.user_registration.options.send_activation_email', false)) { - $this->sendActivationEmail($user); + $this->login->sendActivationEmail($user); } else { if ($this->config->get('plugins.login.user_registration.options.send_welcome_email', false)) { - $this->sendWelcomeEmail($user); + $this->login->sendWelcomeEmail($user); } if ($this->config->get('plugins.login.user_registration.options.send_notification_email', false)) { - $this->sendNotificationEmail($user); + $this->login->sendNotificationEmail($user); } } @@ -624,7 +624,7 @@ public function onFormProcessed(Event $event) switch ($action) { case 'register_user': - $this->processUserRegistration($form); + $this->processUserRegistration($form, $event); break; } } From d2e8c57ce285bef048d17c328fe2e725ebbe0ab0 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 2 May 2016 18:31:42 +0200 Subject: [PATCH 43/68] Fix logout on homepage, trailing slash issue. Improve login/logout form. Translate Welcome message. Translate logout button. --- languages.yaml | 1 + templates/partials/login-form.html.twig | 68 +++++++++++------------ templates/partials/login-status.html.twig | 2 +- 3 files changed, 35 insertions(+), 36 deletions(-) mode change 100644 => 100755 languages.yaml mode change 100644 => 100755 templates/partials/login-form.html.twig mode change 100644 => 100755 templates/partials/login-status.html.twig diff --git a/languages.yaml b/languages.yaml old mode 100644 new mode 100755 index 2086862..38cdec9 --- a/languages.yaml +++ b/languages.yaml @@ -79,6 +79,7 @@ en: TIMEOUT_HELP: "Sets the session timeout in seconds when Remember Me is enabled and checked by the user. Minimum is 604800 which means 1 week" GROUPS_HELP: "List of groups the new registered user will be part of, if any" SITE_ACCESS_HELP: "List of site access levels the new registered user will have. Example: `login` -> `true` " + WELCOME: "Welcome" fr: PLUGIN_LOGIN: diff --git a/templates/partials/login-form.html.twig b/templates/partials/login-form.html.twig old mode 100644 new mode 100755 index a54b0ee..e9bbb6b --- a/templates/partials/login-form.html.twig +++ b/templates/partials/login-form.html.twig @@ -1,52 +1,50 @@ {% set icons = {'Microsoft': 'windows'} %}
- {% if page.template == 'login' %} - {{ content }} - {% endif %} - {% include 'partials/messages.html.twig' %} {% if page.template == 'login' %} - - {% if grav.twig.plugins_hooked_loginPage %} - {% for label in grav.twig.plugins_hooked_loginPage %} + {% if grav.user.username %} +

{{ 'PLUGIN_LOGIN.WELCOME'|t }} {{ grav.user.fullname ?: grav.user.username }}

+
+ {{ 'PLUGIN_LOGIN.BTN_LOGOUT'|t }} + + {% else %} + {{ content }} + + + {% if grav.twig.plugins_hooked_loginPage %} + {% for label in grav.twig.plugins_hooked_loginPage %} + {% include label %} + {% endfor %} + {% endif %} - {% include label %} + {% for field in page.header.form.fields %} + {% if field.type %} +
+ {% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %} +
+ {% endif %} {% endfor %} - {% endif %} - - {% for field in page.header.form.fields %} - {% if field.type %} -
- {% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %} -
- {% endif %} - {% endfor %} -
- {% if config.plugins.login.rememberme.enabled %} -
-
- - +
+ {% if config.plugins.login.rememberme.enabled %} +
+
+ + +
-
- {% endif %} + {% endif %} - {{ 'PLUGIN_LOGIN.BTN_FORGOT'|t }} + {{ 'PLUGIN_LOGIN.BTN_FORGOT'|t }} - -
+ +
- {{ nonce_field('login-form', 'login-form-nonce') }} - + {{ nonce_field('login-form', 'login-form-nonce') }} + - {% else %} - - {% if grav.user.username %} -
- Logout {% endif %} {% endif %} diff --git a/templates/partials/login-status.html.twig b/templates/partials/login-status.html.twig old mode 100644 new mode 100755 index d4ab4f2..f4a55c2 --- a/templates/partials/login-status.html.twig +++ b/templates/partials/login-status.html.twig @@ -1,5 +1,5 @@ From c1ab3bf00610351e0a6a728a7f5a978c6ea59dbd Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 2 May 2016 18:35:12 +0200 Subject: [PATCH 44/68] Fill changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 284e673..aaefe5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v2.0.0-beta.2 +## 05/02/2016 + +1. [](#improved) + * Improved the login form page once logged in + * Translate welcome and logout strings +1. [](#bugfix) + * Fixed logging out on the homepage + * Fixed an issue in processing user registration + # v2.0.0-beta.1 ## 04/20/2016 From 832b80c8c71d104940b47ce10a41a8f2bc698837 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Mon, 2 May 2016 18:38:50 +0200 Subject: [PATCH 45/68] Bump year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 0e788c6..4bb7092 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Grav +Copyright (c) 2016 Grav Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 896782782674f0cca8861d03aec5b26de552f900 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 3 May 2016 15:49:39 -0600 Subject: [PATCH 46/68] version update --- CHANGELOG.md | 2 +- blueprints.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aaefe5b..ec0e425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v2.0.0-beta.2 -## 05/02/2016 +## 05/03/2016 1. [](#improved) * Improved the login form page once logged in diff --git a/blueprints.yaml b/blueprints.yaml index 3bbe0f9..68f36d8 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,5 +1,5 @@ name: Login -version: 2.0.0-beta.1 +version: 2.0.0-beta.2 testing: true description: Enables user authentication and login screen. icon: sign-in From d1739923f08f2da4e1c6b80d7c326f54e4290ba6 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Thevenet Date: Wed, 4 May 2016 16:17:18 -0400 Subject: [PATCH 47/68] :fr: updated + reordering other languages than en :fr: updated + reordering other languages than en --- languages.yaml | 120 +++++++++++++++++++++++++++---------------------- 1 file changed, 67 insertions(+), 53 deletions(-) diff --git a/languages.yaml b/languages.yaml index 38cdec9..bce4003 100755 --- a/languages.yaml +++ b/languages.yaml @@ -80,11 +80,58 @@ en: GROUPS_HELP: "List of groups the new registered user will be part of, if any" SITE_ACCESS_HELP: "List of site access levels the new registered user will have. Example: `login` -> `true` " WELCOME: "Welcome" + +de: + PLUGIN_LOGIN: + USERNAME: Benutzername + PASSWORD: Passwort + ACCESS_DENIED: Zugang verweigert + LOGIN_FAILED: Login fehlgeschlagen... + LOGIN_SUCCESSFUL: Du wurdest erfolgreich eingeloggt. + BTN_LOGIN: Anmelden + BTN_LOGOUT: Ausloggen + BTN_FORGOT: Vergessen + BTN_REGISTER: Registrieren + REMEMBER_ME: Angemeldet bleiben + REMEMBER_ME_HELP: "Speichert einen Cookie im Browser, welcher eine fortwährende Anmeldung sicherstellt." + BUILTIN_CSS: "Nutze das integrierte CSS" + BUILTIN_CSS_HELP: "Nutze das CSS, welches vom Admin Plugin bereitgestellt werden" + ROUTE: "Anmeldepfad" + ROUTE_REGISTER: "Registrierungspfad" + USERNAME_NOT_AVAILABLE: "Der Nutzername %s existiert bereits, bitte wähle einen Anderen" + EMAIL_NOT_CONFIGURED: "E-Mail ist nicht konfiguriert" + USER_NEEDS_EMAIL_FIELD: "Der Nutzer benötigt ein E-Mail Feld" + EMAIL_SENDING_FAILURE: "Ein Fehler ist beim senden der E-Mail aufgetreten" + ACTIVATION_EMAIL_SUBJECT: "Aktiviere dein Account auf %s" + ACTIVATION_EMAIL_BODY: "Hi %s, click %s to activate your account on %s" + WELCOME_EMAIL_SUBJECT: "Willkommen zu %s" + WELCOME_EMAIL_BODY: "Hi %s, willkommen zu %s!" + NOTIFICATION_EMAIL_SUBJECT: "Neuer Nutzer auf %s" + NOTIFICATION_EMAIL_BODY: "Hi, ein neuer Nutzer hat sich auf %s registriert. Nutzername: %s, E-Mail: %s" + EMAIL_FOOTER: "GetGrav.org" + ACTIVATION_LINK_EXPIRED: "Aktivierungslink ist abgelaufen" + USER_ACTIVATED_SUCCESSFULLY: "Nutzer erfolgreich aktiviert" + INVALID_REQUEST: "Ungültige Anfrage" + USER_REGISTRATION: "Nutzer Registrierung" + USER_REGISTRATION_ENABLED_HELP: "Aktiviere die Nutzer Registrierung" + VALIDATE_PASSWORD1_AND_PASSWORD2: "Überprüfe das doppelt eingegebene Passwort" + SEND_ACTIVATION_EMAIL: "Aktivierungs E-Mail senden" + SEND_NOTIFICATION_EMAIL: "Benachtichtigungs E-Mail senden" + SEND_WELCOME_EMAIL: "Sende eine Willkommens E-Mail" + DEFAULT_VALUES: "Standard Werte" + ADDITIONAL_PARAM_KEY: "Parameter" + ADDITIONAL_PARAM_VALUE: "Wert" + REGISTRATION_FIELDS: "Registrierungsfelder" + REGISTRATION_FIELD_KEY: "Feldname" + REDIRECT_AFTER_LOGIN: "Umleitung nach Login" + REDIRECT_AFTER_REGISTRATION: "Umleitung nach Registrierung" + OPTIONS: Optionen + EMAIL_VALIDATION_MESSAGE: "Muss eine gültige E-Mail Adresse sein" fr: PLUGIN_LOGIN: - USERNAME: "Nom d'utilisateur" - PASSWORD: "Mot de passe" + USERNAME: Nom d'utilisateur + PASSWORD: Mot de passe ACCESS_DENIED: Accès refusé... LOGIN_FAILED: Échec de la connexion... LOGIN_SUCCESSFUL: Vous vous êtes connecté avec succès. @@ -92,18 +139,31 @@ fr: BTN_LOGOUT: Déconnexion BTN_FORGOT: Mot de passe oublié BTN_REGISTER: S'enregister + BTN_RESET: "Réinitialiser le mot de passe" + BTN_SEND_INSTRUCTIONS: "Envoyer les instructions de Réinitialisation" + RESET_LINK_EXPIRED: "Le lien de réinitialisation a expiré, veuillez réessayer" + RESET_PASSWORD_RESET: "Le mot de passe a été réinitialisé" + RESET_INVALID_LINK: "Le lien de réinitialisation utilisé n'est pas valide, veuillez réessayer" + FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL: "Les instructions pour la réinitialisation de votre mot de passe ont été envoyées par e-mail à %s" + FORGOT_FAILED_TO_EMAIL: "Impossible d'envoyer les instructions, veuillez réessayer ultérieurement" + FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL: "Impossible de réinitialiser le mot de passe pour %s, aucune adresse e-mail n'a été paramétrée" + FORGOT_USERNAME_DOES_NOT_EXIST: "L'utilisateur avec le nom d'utilisateur %s n'existe pas" + FORGOT_EMAIL_NOT_CONFIGURED: "Impossible de réinitialiser le mot de passe. Ce site n'est pas configuré pour envoyer des e-mails" + FORGOT_EMAIL_SUBJECT: "Demande de réinitialisation de mot de passe %s" + FORGOT_EMAIL_BODY: "

Réinitialisation de mot de passe

%1$s,

Une demande a été faite sur %4$s pour la réinitialisation de votre mot de passe.


Cliquez ici pour réinitialiser votre mot de passe

Vous pouvez également copier l'URL suivante dans la barre d'adresse de votre navigateur :

%2$s


Cordialement,

%3$s

" + SESSION: "Session - “Se souvenir de moi”" REMEMBER_ME: Se souvenir de moi - REMEMBER_ME_HELP: "Définit un cookie sur votre navigateur pour permettant l'authentification par connexion persistante entre les sessions." + REMEMBER_ME_HELP: "Définit un cookie persistant sur votre navigateur autorisant l'authentification par connexion persistante entre les sessions." REMEMBER_ME_STOLEN_COOKIE: "Quelqu'un d'autre a utilisé vos informations de connexion pour accéder à cette page ! Toutes les sessions ont été déconnectées. Veuillez vous connecter avec vos identifiants et vérifier vos données." BUILTIN_CSS: Utiliser les CSS intégrés BUILTIN_CSS_HELP: Utiliser les CSS fournis dans le plugin d'administration ROUTE: Chemin de connexion ROUTE_HELP: Chemin personnalisé vers une page de connexion personnalisée proposée par votre thème - ROUTE_REGISTER: "Chemin vers l'inscription" - ROUTE_REGISTER_HELP: "Chemin vers la page d'inscription. A définir si vous souhaitez utiliser la page d'inscription intégrée. Laisser vide si vous disposez de votre propre formulaire d'inscription." + ROUTE_REGISTER: Chemin vers l'inscription + ROUTE_REGISTER_HELP: Chemin vers la page d'inscription. A définir si vous souhaitez utiliser la page d'inscription intégrée. Laisser vide si vous disposez de votre propre formulaire d'inscription. USERNAME_NOT_VALID: "Le nom d'utilisateur doit comporter entre 3 et 16 caractères et peut être composé de lettres minuscules, de chiffres et de tirets de soulignement (underscores) et des traits d'union. Les lettres majuscules, les espaces et les caractères spéciaux ne sont pas autorisés." USERNAME_NOT_AVAILABLE: "Le nom d'utilisateur %s existe déjà, veuillez en choisir un autre." - PASSWORD_NOT_VALID: "Le mot de passe doit-être composé d'au moins un chiffre, une majuscule et une minuscule, et au moins 8 caractères" + PASSWORD_NOT_VALID: "Le mot de passe doit contenir au moins un chiffre, une majuscule et une minuscule et être composé d'au moins 8 caractères" PASSWORDS_DO_NOT_MATCH: "Les mots de passe sont différents. Réessayez de saisir le même mot de passe deux fois." EMAIL_NOT_CONFIGURED: "L'e-mail n'est pas configuré" USER_NEEDS_EMAIL_FIELD: "L'utilisateur a besoin d'un champ pour e-mail" @@ -149,6 +209,7 @@ fr: TIMEOUT_HELP: "Définit le délai d'expiration de la session en secondes lorsque 'Se souvenir de moi' est activé et coché par l'utilisateur. Minimum de 604800 ce qui correspond à 1 semaine." GROUPS_HELP: "Liste des groupes auxquels le nouvel utilisateur enregistré fera partie, le cas échéant." SITE_ACCESS_HELP: "Liste des niveaux d'accès au site attribués au nouvel utilisateur enregistré. Exemple : `login` -> `true` " + WELCOME: "Bienvenue" hr: PLUGIN_LOGIN: @@ -217,50 +278,3 @@ hu: USERNAME_NOT_AVAILABLE: "%s nevű felhasználó már létezik, kérlek válassz más felhasználónevet" PASSWORD_NOT_VALID: "A jelszónak tartalmaznia kell legalább egy számot, egy kisbetűt és egy nagybetűt, valamint legalább 8 karakter hosszú kell, hogy legyen" PASSWORDS_DO_NOT_MATCH: "A két jelszó nem egyezik meg. Győzödj meg róla, hogy azonos legyen a kettő" - -de: - PLUGIN_LOGIN: - USERNAME: Benutzername - PASSWORD: Passwort - ACCESS_DENIED: Zugang verweigert - LOGIN_FAILED: Login fehlgeschlagen... - LOGIN_SUCCESSFUL: Du wurdest erfolgreich eingeloggt. - BTN_LOGIN: Anmelden - BTN_LOGOUT: Ausloggen - BTN_FORGOT: Vergessen - BTN_REGISTER: Registrieren - REMEMBER_ME: Angemeldet bleiben - REMEMBER_ME_HELP: "Speichert einen Cookie im Browser, welcher eine fortwährende Anmeldung sicherstellt." - BUILTIN_CSS: "Nutze das integrierte CSS" - BUILTIN_CSS_HELP: "Nutze das CSS, welches vom Admin Plugin bereitgestellt werden" - ROUTE: "Anmeldepfad" - ROUTE_REGISTER: "Registrierungspfad" - USERNAME_NOT_AVAILABLE: "Der Nutzername %s existiert bereits, bitte wähle einen Anderen" - EMAIL_NOT_CONFIGURED: "E-Mail ist nicht konfiguriert" - USER_NEEDS_EMAIL_FIELD: "Der Nutzer benötigt ein E-Mail Feld" - EMAIL_SENDING_FAILURE: "Ein Fehler ist beim senden der E-Mail aufgetreten" - ACTIVATION_EMAIL_SUBJECT: "Aktiviere dein Account auf %s" - ACTIVATION_EMAIL_BODY: "Hi %s, click %s to activate your account on %s" - WELCOME_EMAIL_SUBJECT: "Willkommen zu %s" - WELCOME_EMAIL_BODY: "Hi %s, willkommen zu %s!" - NOTIFICATION_EMAIL_SUBJECT: "Neuer Nutzer auf %s" - NOTIFICATION_EMAIL_BODY: "Hi, ein neuer Nutzer hat sich auf %s registriert. Nutzername: %s, E-Mail: %s" - EMAIL_FOOTER: "GetGrav.org" - ACTIVATION_LINK_EXPIRED: "Aktivierungslink ist abgelaufen" - USER_ACTIVATED_SUCCESSFULLY: "Nutzer erfolgreich aktiviert" - INVALID_REQUEST: "Ungültige Anfrage" - USER_REGISTRATION: "Nutzer Registrierung" - USER_REGISTRATION_ENABLED_HELP: "Aktiviere die Nutzer Registrierung" - VALIDATE_PASSWORD1_AND_PASSWORD2: "Überprüfe das doppelt eingegebene Passwort" - SEND_ACTIVATION_EMAIL: "Aktivierungs E-Mail senden" - SEND_NOTIFICATION_EMAIL: "Benachtichtigungs E-Mail senden" - SEND_WELCOME_EMAIL: "Sende eine Willkommens E-Mail" - DEFAULT_VALUES: "Standard Werte" - ADDITIONAL_PARAM_KEY: "Parameter" - ADDITIONAL_PARAM_VALUE: "Wert" - REGISTRATION_FIELDS: "Registrierungsfelder" - REGISTRATION_FIELD_KEY: "Feldname" - REDIRECT_AFTER_LOGIN: "Umleitung nach Login" - REDIRECT_AFTER_REGISTRATION: "Umleitung nach Registrierung" - OPTIONS: Optionen - EMAIL_VALIDATION_MESSAGE: "Muss eine gültige E-Mail Adresse sein" From b8ba07df29dbb7af200d3be04a19c6d9712cd1cd Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Wed, 11 May 2016 11:54:51 +0200 Subject: [PATCH 48/68] Add a "Redirect after the user activation" option, fix #70 --- blueprints.yaml | 8 +++++++- languages.yaml | 8 +++++--- login.php | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index 68f36d8..f3f59e2 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -140,7 +140,13 @@ form: type: text label: PLUGIN_LOGIN.REDIRECT_AFTER_REGISTRATION help: PLUGIN_LOGIN.REDIRECT_AFTER_REGISTRATION_HELP - placeholder: "/my-page" + placeholder: "/page-to-show-after-registration" + + user_registration.redirect_after_activation: + type: text + label: PLUGIN_LOGIN.REDIRECT_AFTER_ACTIVATION + help: PLUGIN_LOGIN.REDIRECT_AFTER_ACTIVATION_HELP + placeholder: "/page-to-show-after-activation" registration_fields: type: section diff --git a/languages.yaml b/languages.yaml index 38cdec9..fb5ee1f 100755 --- a/languages.yaml +++ b/languages.yaml @@ -39,7 +39,7 @@ en: USER_NEEDS_EMAIL_FIELD: "The user needs an email field" EMAIL_SENDING_FAILURE: "An error occurred while sending the email" ACTIVATION_EMAIL_SUBJECT: "Activate your account on %s" - ACTIVATION_EMAIL_BODY: "Hi %s, click %s to activate your account on %s" + ACTIVATION_EMAIL_BODY: "Hi %s, click here to activate your account on %s" WELCOME_EMAIL_SUBJECT: "Welcome to %s" WELCOME_EMAIL_BODY: "Hi %s, welcome to %s!" NOTIFICATION_EMAIL_SUBJECT: "New user on %s" @@ -80,6 +80,8 @@ en: GROUPS_HELP: "List of groups the new registered user will be part of, if any" SITE_ACCESS_HELP: "List of site access levels the new registered user will have. Example: `login` -> `true` " WELCOME: "Welcome" + REDIRECT_AFTER_ACTIVATION: "Redirect after the user activation" + REDIRECT_AFTER_ACTIVATION_HELP: "Used if the user is required to activate the account via email. Once activated, this route will be shown" fr: PLUGIN_LOGIN: @@ -109,7 +111,7 @@ fr: USER_NEEDS_EMAIL_FIELD: "L'utilisateur a besoin d'un champ pour e-mail" EMAIL_SENDING_FAILURE: "Une erreur est survenue lors de l'envoi de l'e-mail." ACTIVATION_EMAIL_SUBJECT: "Activer votre compte sur %s" - ACTIVATION_EMAIL_BODY: "Bonjour %s, cliquez sur %s pour activer votre compte sur %s" + ACTIVATION_EMAIL_BODY: "Bonjour %s, cliquez pour activer votre compte sur %s" WELCOME_EMAIL_SUBJECT: "Bienvenue sur %s" WELCOME_EMAIL_BODY: "Bonjour %s, bienvenue sur %s!" NOTIFICATION_EMAIL_SUBJECT: "Nouvel utilisateur sur %s" @@ -240,7 +242,7 @@ de: USER_NEEDS_EMAIL_FIELD: "Der Nutzer benötigt ein E-Mail Feld" EMAIL_SENDING_FAILURE: "Ein Fehler ist beim senden der E-Mail aufgetreten" ACTIVATION_EMAIL_SUBJECT: "Aktiviere dein Account auf %s" - ACTIVATION_EMAIL_BODY: "Hi %s, click %s to activate your account on %s" + ACTIVATION_EMAIL_BODY: "Hi %s, click here to activate your account on %s" WELCOME_EMAIL_SUBJECT: "Willkommen zu %s" WELCOME_EMAIL_BODY: "Hi %s, willkommen zu %s!" NOTIFICATION_EMAIL_SUBJECT: "Neuer Nutzer auf %s" diff --git a/login.php b/login.php index 3469bb1..f60abf2 100755 --- a/login.php +++ b/login.php @@ -317,11 +317,11 @@ public function handleUserActivation() } else { $message = $this->grav['language']->translate('PLUGIN_LOGIN.INVALID_REQUEST'); $messages->add($message, 'error'); - } } - $this->grav->redirect('/'); + $redirect_route = $this->config->get('plugins.login.user_registration.redirect_after_activation', '/'); + $this->grav->redirect($redirect_route); } /** From 109f7f75fcd52597bf4fca9f94084a1490573a83 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Thevenet Date: Fri, 13 May 2016 07:56:49 -0400 Subject: [PATCH 49/68] :fr: updated :fr: updated --- languages.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/languages.yaml b/languages.yaml index 8cf1c57..dfeaf55 100755 --- a/languages.yaml +++ b/languages.yaml @@ -212,6 +212,8 @@ fr: GROUPS_HELP: "Liste des groupes auxquels le nouvel utilisateur enregistré fera partie, le cas échéant." SITE_ACCESS_HELP: "Liste des niveaux d'accès au site attribués au nouvel utilisateur enregistré. Exemple : `login` -> `true` " WELCOME: "Bienvenue" + REDIRECT_AFTER_ACTIVATION: "Redirection après l’activation de l’utilisateur" + REDIRECT_AFTER_ACTIVATION_HELP: "Utilisé s'il est nécessaire pour l’utilisateur d'activer le compte par e-mail. Une fois activé, ce chemin s’affichera" hr: PLUGIN_LOGIN: From 020e77394f57f69d0571ff380749f99066969311 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Sun, 15 May 2016 16:37:58 -0400 Subject: [PATCH 50/68] Fixes #74 --- classes/Controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/Controller.php b/classes/Controller.php index 9c6324b..8877959 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -183,7 +183,7 @@ protected function taskForgot() if (!$user || !$user->exists()) { $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error'); - $this->setRedirect('/forgot'); + $this->setRedirect($this->grav['config']->get('plugins.login.route_forgot')); return true; } From 640c85b4fa5b840f3523908dc0dcb39ac88be867 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Sun, 15 May 2016 16:41:18 -0400 Subject: [PATCH 51/68] Change more hardcoded routes to config based --- classes/Controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Controller.php b/classes/Controller.php index 8877959..a02165f 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -191,7 +191,7 @@ protected function taskForgot() if (empty($user->email)) { $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]), 'error'); - $this->setRedirect('/forgot'); + $this->setRedirect($this->grav['config']->get('plugins.login.route_forgot')); return true; } @@ -212,7 +212,7 @@ protected function taskForgot() if (empty($from)) { $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error'); - $this->setRedirect('/forgot'); + $this->setRedirect($this->grav['config']->get('plugins.login.route_forgot')); return true; } From 34b12ce4d65c25f769c0a6b98a5c5726d53f8004 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 19 May 2016 16:16:06 -0600 Subject: [PATCH 52/68] typo in comment --- login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/login.php b/login.php index 3469bb1..82574c6 100755 --- a/login.php +++ b/login.php @@ -202,7 +202,7 @@ public function addForgotPage() $page = $pages->dispatch($route); if (!$page) { - // Only add login page if it hasn't already been defined. + // Only add forgot page if it hasn't already been defined. $page = new Page; $page->init(new \SplFileInfo(__DIR__ . "/pages/forgot.md")); $page->slug(basename($route)); From d3cc20e6ad22ea2d690be88496c2bc9c0553f217 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 19 May 2016 16:16:22 -0600 Subject: [PATCH 53/68] don't error out when HTTP_USER_AGENT is not set --- classes/Controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/Controller.php b/classes/Controller.php index 9c6324b..8a1f2ac 100644 --- a/classes/Controller.php +++ b/classes/Controller.php @@ -405,7 +405,8 @@ public function rememberMe($var = null) // Hardening cookies with user-agent and random salt or // fallback to use system based cache key - $data = $_SERVER['HTTP_USER_AGENT'] . $config->get('security.salt', $this->grav['cache']->getKey()); + $server_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'unknown'; + $data = $server_agent . $config->get('security.salt', $this->grav['cache']->getKey()); $this->rememberMe->setSalt(hash('sha512', $data)); // Set cookie with correct base path of Grav install From 1b749278b38fc93d026ff2156aaa9d093df478c9 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 23 May 2016 14:17:32 -0600 Subject: [PATCH 54/68] login updates --- CHANGELOG.md | 10 ++++++++++ blueprints.yaml | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec0e425..4a2a981 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v2.0.0-beta.3 +## 05/23/2016 + +1. [](#improved) + * Added a redirect after activation + * Changed hardcoded redirect routes to config-based +1. [](#bugfix) + * Fix a redirect issue #74 + * Don't error if missing a HTTP_USER_AGENT browser string + # v2.0.0-beta.2 ## 05/03/2016 diff --git a/blueprints.yaml b/blueprints.yaml index f3f59e2..67bb8b4 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,5 +1,5 @@ name: Login -version: 2.0.0-beta.2 +version: 2.0.0-beta.3 testing: true description: Enables user authentication and login screen. icon: sign-in From e5403b500936f018e7c38281c515c53f4ee8d437 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 31 May 2016 13:11:11 +0200 Subject: [PATCH 55/68] Fix #72 Deny access to the register page when user registration is disabled --- languages.yaml | 1 + login.php | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/languages.yaml b/languages.yaml index dfeaf55..ca8d368 100755 --- a/languages.yaml +++ b/languages.yaml @@ -82,6 +82,7 @@ en: WELCOME: "Welcome" REDIRECT_AFTER_ACTIVATION: "Redirect after the user activation" REDIRECT_AFTER_ACTIVATION_HELP: "Used if the user is required to activate the account via email. Once activated, this route will be shown" + REGISTRATION_DISABLED: "Registration disabled" de: PLUGIN_LOGIN: diff --git a/login.php b/login.php index 9929e08..5281d56 100755 --- a/login.php +++ b/login.php @@ -160,9 +160,14 @@ public function initialize() } if ($uri->path() == $this->config->get('plugins.login.route_register')) { - $this->enable([ - 'onPagesInitialized' => ['addRegisterPage', 0], - ]); + if ($this->config->get('plugins.login.user_registration.enabled')) { + $this->enable([ + 'onPagesInitialized' => ['addRegisterPage', 0], + ]); + } else { + throw new \RuntimeException($this->grav['language']->translate('PLUGIN_LOGIN.REGISTRATION_DISABLED'), 404); + } + } if ($uri->path() == $this->config->get('plugins.login.route_activate')) { From cbc7a1db9e365af1c82b13cfa69a261c01fb8064 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Tue, 31 May 2016 13:11:32 +0200 Subject: [PATCH 56/68] Fix #75 Enable twig processing in the page --- pages/reset.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pages/reset.md b/pages/reset.md index c410367..bf27624 100644 --- a/pages/reset.md +++ b/pages/reset.md @@ -21,6 +21,9 @@ form: - name: token type: hidden + +process: + twig: true --- # Password Reset From 8a7d24cc47eb944420b2127a8c8575ae6cd1c05e Mon Sep 17 00:00:00 2001 From: Marc-Antoine Thevenet Date: Tue, 31 May 2016 09:27:42 -0400 Subject: [PATCH 57/68] :fr: updated + quotes fixes (#80) :fr: updated + quotes fixes --- languages.yaml | 83 +++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/languages.yaml b/languages.yaml index ca8d368..f88a113 100755 --- a/languages.yaml +++ b/languages.yaml @@ -133,44 +133,44 @@ de: fr: PLUGIN_LOGIN: - USERNAME: Nom d'utilisateur - PASSWORD: Mot de passe - ACCESS_DENIED: Accès refusé... - LOGIN_FAILED: Échec de la connexion... - LOGIN_SUCCESSFUL: Vous vous êtes connecté avec succès. - BTN_LOGIN: Connexion - BTN_LOGOUT: Déconnexion - BTN_FORGOT: Mot de passe oublié - BTN_REGISTER: S'enregister + USERNAME: "Nom d’utilisateur" + PASSWORD: "Mot de passe" + ACCESS_DENIED: "Accès refusé..." + LOGIN_FAILED: "Échec de la connexion..." + LOGIN_SUCCESSFUL: "Vous vous êtes connecté avec succès." + BTN_LOGIN: "Connexion" + BTN_LOGOUT: "Déconnexion" + BTN_FORGOT: "Mot de passe oublié" + BTN_REGISTER: "S’enregister" BTN_RESET: "Réinitialiser le mot de passe" BTN_SEND_INSTRUCTIONS: "Envoyer les instructions de Réinitialisation" RESET_LINK_EXPIRED: "Le lien de réinitialisation a expiré, veuillez réessayer" RESET_PASSWORD_RESET: "Le mot de passe a été réinitialisé" RESET_INVALID_LINK: "Le lien de réinitialisation utilisé n'est pas valide, veuillez réessayer" FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL: "Les instructions pour la réinitialisation de votre mot de passe ont été envoyées par e-mail à %s" - FORGOT_FAILED_TO_EMAIL: "Impossible d'envoyer les instructions, veuillez réessayer ultérieurement" + FORGOT_FAILED_TO_EMAIL: "Impossible d’envoyer les instructions, veuillez réessayer ultérieurement" FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL: "Impossible de réinitialiser le mot de passe pour %s, aucune adresse e-mail n'a été paramétrée" - FORGOT_USERNAME_DOES_NOT_EXIST: "L'utilisateur avec le nom d'utilisateur %s n'existe pas" - FORGOT_EMAIL_NOT_CONFIGURED: "Impossible de réinitialiser le mot de passe. Ce site n'est pas configuré pour envoyer des e-mails" + FORGOT_USERNAME_DOES_NOT_EXIST: "L’utilisateur avec le nom d'utilisateur %s n’existe pas" + FORGOT_EMAIL_NOT_CONFIGURED: "Impossible de réinitialiser le mot de passe. Ce site n’est pas configuré pour envoyer des e-mails" FORGOT_EMAIL_SUBJECT: "Demande de réinitialisation de mot de passe %s" - FORGOT_EMAIL_BODY: "

Réinitialisation de mot de passe

%1$s,

Une demande a été faite sur %4$s pour la réinitialisation de votre mot de passe.


Cliquez ici pour réinitialiser votre mot de passe

Vous pouvez également copier l'URL suivante dans la barre d'adresse de votre navigateur :

%2$s


Cordialement,

%3$s

" + FORGOT_EMAIL_BODY: "

Réinitialisation de mot de passe

%1$s,

Une demande a été faite sur %4$s pour la réinitialisation de votre mot de passe.


Cliquez ici pour réinitialiser votre mot de passe

Vous pouvez également copier l’URL suivante dans la barre d’adresse de votre navigateur :

%2$s


Cordialement,

%3$s

" SESSION: "Session - “Se souvenir de moi”" - REMEMBER_ME: Se souvenir de moi - REMEMBER_ME_HELP: "Définit un cookie persistant sur votre navigateur autorisant l'authentification par connexion persistante entre les sessions." - REMEMBER_ME_STOLEN_COOKIE: "Quelqu'un d'autre a utilisé vos informations de connexion pour accéder à cette page ! Toutes les sessions ont été déconnectées. Veuillez vous connecter avec vos identifiants et vérifier vos données." - BUILTIN_CSS: Utiliser les CSS intégrés - BUILTIN_CSS_HELP: Utiliser les CSS fournis dans le plugin d'administration - ROUTE: Chemin de connexion - ROUTE_HELP: Chemin personnalisé vers une page de connexion personnalisée proposée par votre thème - ROUTE_REGISTER: Chemin vers l'inscription - ROUTE_REGISTER_HELP: Chemin vers la page d'inscription. A définir si vous souhaitez utiliser la page d'inscription intégrée. Laisser vide si vous disposez de votre propre formulaire d'inscription. - USERNAME_NOT_VALID: "Le nom d'utilisateur doit comporter entre 3 et 16 caractères et peut être composé de lettres minuscules, de chiffres et de tirets de soulignement (underscores) et des traits d'union. Les lettres majuscules, les espaces et les caractères spéciaux ne sont pas autorisés." - USERNAME_NOT_AVAILABLE: "Le nom d'utilisateur %s existe déjà, veuillez en choisir un autre." + REMEMBER_ME: "Se souvenir de moi" + REMEMBER_ME_HELP: "Définit un cookie persistant sur votre navigateur autorisant l’authentification par connexion persistante entre les sessions." + REMEMBER_ME_STOLEN_COOKIE: "Quelqu’un d'autre a utilisé vos informations de connexion pour accéder à cette page ! Toutes les sessions ont été déconnectées. Veuillez vous connecter avec vos identifiants et vérifier vos données." + BUILTIN_CSS: "Utiliser les CSS intégrés" + BUILTIN_CSS_HELP: "Utiliser les CSS fournis dans le plugin d'administration" + ROUTE: "Chemin de connexion" + ROUTE_HELP: "Chemin personnalisé vers une page de connexion personnalisée proposée par votre thème" + ROUTE_REGISTER: "Chemin vers l'inscription" + ROUTE_REGISTER_HELP: "Chemin vers la page d’inscription. A définir si vous souhaitez utiliser la page d’inscription intégrée. Laisser vide si vous disposez de votre propre formulaire d'inscription." + USERNAME_NOT_VALID: "Le nom d’utilisateur doit comporter entre 3 et 16 caractères et peut être composé de lettres minuscules, de chiffres et de tirets de soulignement (underscores) et des traits d'union. Les lettres majuscules, les espaces et les caractères spéciaux ne sont pas autorisés." + USERNAME_NOT_AVAILABLE: "Le nom d’utilisateur %s existe déjà, veuillez en choisir un autre." PASSWORD_NOT_VALID: "Le mot de passe doit contenir au moins un chiffre, une majuscule et une minuscule et être composé d'au moins 8 caractères" PASSWORDS_DO_NOT_MATCH: "Les mots de passe sont différents. Réessayez de saisir le même mot de passe deux fois." EMAIL_NOT_CONFIGURED: "L'e-mail n'est pas configuré" - USER_NEEDS_EMAIL_FIELD: "L'utilisateur a besoin d'un champ pour e-mail" - EMAIL_SENDING_FAILURE: "Une erreur est survenue lors de l'envoi de l'e-mail." + USER_NEEDS_EMAIL_FIELD: "L’utilisateur a besoin d'un champ pour e-mail" + EMAIL_SENDING_FAILURE: "Une erreur est survenue lors de l’envoi de l'e-mail." ACTIVATION_EMAIL_SUBJECT: "Activer votre compte sur %s" ACTIVATION_EMAIL_BODY: "Bonjour %s, cliquez pour activer votre compte sur %s" WELCOME_EMAIL_SUBJECT: "Bienvenue sur %s" @@ -178,44 +178,45 @@ fr: NOTIFICATION_EMAIL_SUBJECT: "Nouvel utilisateur sur %s" NOTIFICATION_EMAIL_BODY: "Bonjour, un nouvel utilisateur s'est inscrit sur %s. Nom d'utilisateur : %s, e-mail : %s" EMAIL_FOOTER: "GetGrav.org" - ACTIVATION_LINK_EXPIRED: "Le lien d'activation a expiré" + ACTIVATION_LINK_EXPIRED: "Le lien d’activation a expiré" USER_ACTIVATED_SUCCESSFULLY: "Utilisateur activé avec succès" INVALID_REQUEST: "Requête invalide" USER_REGISTRATION: "Inscription de l'utilisateur" USER_REGISTRATION_ENABLED_HELP: "Activer l'inscription des utilisateurs" VALIDATE_PASSWORD1_AND_PASSWORD2: "Valider la double saisie du mot de passe" - VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Comparer et valider deux champs pour les mots de passe `Mot de passe 1` et `Mot de passe 2`. Activez cette option si vous avez deux champs de mots de passe dans le formulaire d'inscription." + VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Comparer et valider deux champs pour les mots de passe `Mot de passe 1` et `Mot de passe 2`. Activez cette option si vous avez deux champs de mots de passe dans le formulaire d’inscription." SET_USER_DISABLED: "Définir l'utilisateur comme désactivé" - SET_USER_DISABLED_HELP: "La meilleure pratique si vous utilisez l'option `Envoyer un e-mail d'activation`. Ajoute l'utilisateur à Grav, mais le défini comme étant désactivé." - LOGIN_AFTER_REGISTRATION: "Connecte l'utilisateur après son inscription" - LOGIN_AFTER_REGISTRATION_HELP: "Identifier immédiatement l'utilisateur après l'inscription. Si l'e-mail d'activation est demandé, l'utilisateur sera connecté immédiatement après l'activation du compte." + SET_USER_DISABLED_HELP: "La meilleure pratique si vous utilisez l’option `Envoyer un e-mail d’activation`. Ajoute l'utilisateur à Grav, mais le défini comme étant désactivé." + LOGIN_AFTER_REGISTRATION: "Connecte l’utilisateur après son inscription" + LOGIN_AFTER_REGISTRATION_HELP: "Identifier immédiatement l’utilisateur après l’inscription. Si l'e-mail d'activation est demandé, l’utilisateur sera connecté immédiatement après l'activation du compte." SEND_ACTIVATION_EMAIL: "Envoyer un e-mail d'activation" - SEND_ACTIVATION_EMAIL_HELP: "Envoyer un e-mail à l'utilisateur pour l'activation son compte. Lorsque vous utilisez cette fonction, activez l'option `Définir l'utilisateur comme désactivé` afin que l'utilisateur soit désactivé et qu'un email lui soit envoyé pour activer son compte." + SEND_ACTIVATION_EMAIL_HELP: "Envoyer un e-mail à l’utilisateur pour l'activation son compte. Lorsque vous utilisez cette fonction, activez l’option `Définir l’utilisateur comme désactivé` afin que l’utilisateur soit désactivé et qu'un e-mail lui soit envoyé pour activer son compte." SEND_NOTIFICATION_EMAIL: "Envoyer un e-mail de notification" - SEND_NOTIFICATION_EMAIL_HELP: "Informe l'administrateur du site qu'un nouvel utilisateur s'est enregistré. L'e-mail sera envoyé à la personne renseignée dans le champ `À` dans la configuration du plugin e-mail." + SEND_NOTIFICATION_EMAIL_HELP: "Informe l’administrateur du site qu'un nouvel utilisateur s’est enregistré. L'e-mail sera envoyé à la personne renseignée dans le champ `À` dans la configuration du plugin e-mail." SEND_WELCOME_EMAIL: "Envoyer un e-mail de bienvenue" SEND_WELCOME_EMAIL_HELP: "Envoyer un e-mail à un nouvel utilisateur enregistré." DEFAULT_VALUES: "Valeurs par défaut" - DEFAULT_VALUES_HELP: "Liste des noms et valeurs associés pour les champs. Ils seront ajoutés au profil utilisateur par défaut (fichier yaml), sans pouvoir être configurables par l'utilisateur. Séparez les différentes valeurs par une virgule, sans espaces entre les valeurs." + DEFAULT_VALUES_HELP: "Liste des noms et valeurs associés pour les champs. Ils seront ajoutés au profil utilisateur par défaut (fichier yaml), sans pouvoir être configurables par l’utilisateur. Séparez les différentes valeurs par une virgule, sans espaces entre les valeurs." ADDITIONAL_PARAM_KEY: "Paramètre" ADDITIONAL_PARAM_VALUE: "Valeur" - REGISTRATION_FIELDS: "Champs d'inscription" - REGISTRATION_FIELDS_HELP: "Ajouter les champs qui seront ajoutés au fichier yaml de l'utilisateur. Les champs non listés ne seront pas ajoutés même s'ils sont présent sur le formulaire d'inscription" + REGISTRATION_FIELDS: "Champs d’inscription" + REGISTRATION_FIELDS_HELP: "Ajouter les champs qui seront ajoutés au fichier yaml de l’utilisateur. Les champs non listés ne seront pas ajoutés même s’ils sont présent sur le formulaire d’inscription" REGISTRATION_FIELD_KEY: "Nom du champ" REDIRECT_AFTER_LOGIN: "Redirection après connexion" REDIRECT_AFTER_LOGIN_HELP: "Chemin personnalisé de redirection après la connexion" REDIRECT_AFTER_REGISTRATION: "Redirection après inscription" - REDIRECT_AFTER_REGISTRATION_HELP: "Chemin personnalisé de redirection après l'inscription" - OPTIONS: Options + REDIRECT_AFTER_REGISTRATION_HELP: "Chemin personnalisé de redirection après l’inscription" + OPTIONS: "Options" EMAIL_VALIDATION_MESSAGE: "Doit-être une adresse e-mail valide" PASSWORD_VALIDATION_MESSAGE: "Le mot de passe doit-être composé d'au moins un chiffre, une majuscule et une minuscule, et au moins 8 caractères" - TIMEOUT_HELP: "Définit le délai d'expiration de la session en secondes lorsque 'Se souvenir de moi' est activé et coché par l'utilisateur. Minimum de 604800 ce qui correspond à 1 semaine." + TIMEOUT_HELP: "Définit le délai d'expiration de la session en secondes lorsque 'Se souvenir de moi' est activé et coché par l’utilisateur. Minimum de 604800 ce qui correspond à 1 semaine." GROUPS_HELP: "Liste des groupes auxquels le nouvel utilisateur enregistré fera partie, le cas échéant." SITE_ACCESS_HELP: "Liste des niveaux d'accès au site attribués au nouvel utilisateur enregistré. Exemple : `login` -> `true` " WELCOME: "Bienvenue" REDIRECT_AFTER_ACTIVATION: "Redirection après l’activation de l’utilisateur" - REDIRECT_AFTER_ACTIVATION_HELP: "Utilisé s'il est nécessaire pour l’utilisateur d'activer le compte par e-mail. Une fois activé, ce chemin s’affichera" - + REDIRECT_AFTER_ACTIVATION_HELP: "Utilisé s’il est nécessaire pour l’utilisateur d'activer le compte par e-mail. Une fois activé, ce chemin s’affichera" + REGISTRATION_DISABLED: "Inscription désactivée" + hr: PLUGIN_LOGIN: ACCESS_DENIED: Pristup odbijen... From 55cb48556f1128997f10f6dfe2788a2cd25c80fa Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 1 Jun 2016 17:49:46 -0600 Subject: [PATCH 58/68] version update --- CHANGELOG.md | 21 +++++++++++++++------ blueprints.yaml | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a2a981..a7ecacd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v2.0.0-rc.1 +## 06/01/2016 + +1. [](#improved) + * French updated +1. [](#bugfix) + * Enable twig processing in a page #75 + * Deny access to registration when user registration is disabled #72 + # v2.0.0-beta.3 ## 05/23/2016 @@ -7,7 +16,7 @@ 1. [](#bugfix) * Fix a redirect issue #74 * Don't error if missing a HTTP_USER_AGENT browser string - + # v2.0.0-beta.2 ## 05/03/2016 @@ -17,7 +26,7 @@ 1. [](#bugfix) * Fixed logging out on the homepage * Fixed an issue in processing user registration - + # v2.0.0-beta.1 ## 04/20/2016 @@ -45,7 +54,7 @@ * Add the correct message type when raising a form processing error 1. [](#bugfix) * Show the correct error message when the user is not authorized to view a page - * Fix showing the OAuth links in the login form + * Fix showing the OAuth links in the login form # v1.3.0 ## 01/06/2016 @@ -96,7 +105,7 @@ * Check page exists so as not to fail hard * Fix for static Inflector references #17 - + # v1.0.1 ## 11/23/2015 @@ -170,7 +179,7 @@ * Add the correct message type when raising a form processing error 1. [](#bugfix) * Show the correct error message when the user is not authorized to view a page - * Fix showing the OAuth links in the login form + * Fix showing the OAuth links in the login form # v1.3.0 ## 01/06/2016 @@ -221,7 +230,7 @@ * Check page exists so as not to fail hard * Fix for static Inflector references #17 - + # v1.0.1 ## 11/23/2015 diff --git a/blueprints.yaml b/blueprints.yaml index 67bb8b4..6e9c275 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,5 +1,5 @@ name: Login -version: 2.0.0-beta.3 +version: 2.0.0-rc.1 testing: true description: Enables user authentication and login screen. icon: sign-in From de88bc0fe4c93d70f388b06eef2b3e7b1a26f187 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Fri, 17 Jun 2016 19:33:02 +0200 Subject: [PATCH 59/68] Fix commented error message. Use correct error level --- login.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/login.php b/login.php index 5281d56..eb7f2a4 100755 --- a/login.php +++ b/login.php @@ -344,7 +344,7 @@ public function loginController() if ($task == 'login') { if (!isset($post['login-form-nonce']) || !Utils::verifyNonce($post['login-form-nonce'], 'login-form')) { $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), - 'info'); + 'error'); $this->authenticated = false; $twig = $this->grav['twig']; $twig->twig_vars['notAuthorized'] = true; @@ -363,7 +363,7 @@ public function loginController() 'forgot-form') ) { $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), - 'info'); + 'error'); return; } @@ -372,8 +372,8 @@ public function loginController() if (!isset($post['reset-form-nonce']) || !Utils::verifyNonce($post['reset-form-nonce'], 'reset-form') ) { - //$this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info'); - //return; + $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'error'); + return; } } } @@ -462,7 +462,7 @@ public function authorizePage() unset($this->grav['page']); $this->grav['page'] = $page; } else { - $this->grav['messages']->add($l->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info'); + $this->grav['messages']->add($l->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'error'); $this->authenticated = false; $twig = $this->grav['twig']; From 282e90874c71a6200093bf43c4210dfac4fdd181 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Fri, 17 Jun 2016 19:40:16 +0200 Subject: [PATCH 60/68] Fix #45 allow to protect page media --- blueprints.yaml | 16 ++++++++++++++-- languages.yaml | 2 ++ login.php | 13 +++++++++++++ login.yaml | 1 + 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index 6e9c275..021ee4b 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -76,8 +76,20 @@ form: default: 0 help: "Check for parent access rules if no rules are defined" options: - 1: Enabled - 0: Disabled + 1: PLUGIN_ADMIN.ENABLED + 0: PLUGIN_ADMIN.DISABLED + validate: + type: bool + + protect_protected_page_media: + type: toggle + label: PLUGIN_LOGIN.PROTECT_PROTECTED_PAGE_MEDIA_LABEL + highlight: 1 + default: 0 + help: PLUGIN_LOGIN.PROTECT_PROTECTED_PAGE_MEDIA_HELP + options: + 1: PLUGIN_ADMIN.ENABLED + 0: PLUGIN_ADMIN.DISABLED validate: type: bool diff --git a/languages.yaml b/languages.yaml index f88a113..7ae67ef 100755 --- a/languages.yaml +++ b/languages.yaml @@ -83,6 +83,8 @@ en: REDIRECT_AFTER_ACTIVATION: "Redirect after the user activation" REDIRECT_AFTER_ACTIVATION_HELP: "Used if the user is required to activate the account via email. Once activated, this route will be shown" REGISTRATION_DISABLED: "Registration disabled" + PROTECT_PROTECTED_PAGE_ASSETS_LABEL: "Protect protected page assets" + PROTECT_PROTECTED_PAGE_ASSETS_HELP: "If enabled, media of a login protected page is login protected as well and cannot be seen unless logged in" de: PLUGIN_LOGIN: diff --git a/login.php b/login.php index eb7f2a4..2e8be92 100755 --- a/login.php +++ b/login.php @@ -53,6 +53,7 @@ public static function getSubscribedEvents() 'onTask.login.logout' => ['loginController', 0], 'onTask.login.reset' => ['loginController', 0], 'onPageInitialized' => ['authorizePage', 0], + 'onPageFallBackUrl' => ['authorizeFallBackUrl', 0], 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0], 'onTwigSiteVariables' => ['onTwigSiteVariables', -100000], 'onFormProcessed' => ['onFormProcessed', 0] @@ -386,6 +387,18 @@ public function loginController() $controller->redirect(); } + /** + * Authorize the Page fallback url (page media accessed through the page route) + */ + public function authorizeFallBackUrl() + { + if ($this->config->get('plugins.login.protect_protected_page_media', false)) { + $page_url = dirname($this->grav['uri']->path()); + $page = $this->grav['pages']->find($page_url); + $this->grav['page'] = $page; + $this->authorizePage(); + } + } /** * Authorize Page diff --git a/login.yaml b/login.yaml index baff264..95a50c1 100644 --- a/login.yaml +++ b/login.yaml @@ -7,6 +7,7 @@ route_forgot: /forgot_password route_reset: /reset_password redirect_after_login: parent_acl: false +protect_protected_page_media: false user_registration: enabled: true From d9c73284da3b267de6ff90910565e7acb6dfb245 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Fri, 17 Jun 2016 19:40:24 +0200 Subject: [PATCH 61/68] Translate blueprint item --- blueprints.yaml | 4 ++-- languages.yaml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index 021ee4b..bf67358 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -71,10 +71,10 @@ form: parent_acl: type: toggle - label: Use parent access rules + label: PLUGIN_LOGIN.USE_PARENT_ACL_LABEL highlight: 1 default: 0 - help: "Check for parent access rules if no rules are defined" + help: PLUGIN_LOGIN.USE_PARENT_ACL_HELP options: 1: PLUGIN_ADMIN.ENABLED 0: PLUGIN_ADMIN.DISABLED diff --git a/languages.yaml b/languages.yaml index 7ae67ef..fde85a4 100755 --- a/languages.yaml +++ b/languages.yaml @@ -83,6 +83,8 @@ en: REDIRECT_AFTER_ACTIVATION: "Redirect after the user activation" REDIRECT_AFTER_ACTIVATION_HELP: "Used if the user is required to activate the account via email. Once activated, this route will be shown" REGISTRATION_DISABLED: "Registration disabled" + USE_PARENT_ACL_LABEL: "Use parent access rules" + USE_PARENT_ACL_HELP: "Check for parent access rules if no rules are defined" PROTECT_PROTECTED_PAGE_ASSETS_LABEL: "Protect protected page assets" PROTECT_PROTECTED_PAGE_ASSETS_HELP: "If enabled, media of a login protected page is login protected as well and cannot be seen unless logged in" From 016dac7095165d331a1faa220551e8bbb5f43a72 Mon Sep 17 00:00:00 2001 From: Flavio Copes Date: Fri, 17 Jun 2016 19:43:23 +0200 Subject: [PATCH 62/68] Changelog --- CHANGELOG.md | 8 ++++++++ languages.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7ecacd..93e46a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# v2.0.0-rc.2 +## 06/17/2016 + +1. [](#new) + * Add an option to login protect a login-protected page media accessed through the page route [#45](https://github.com/getgrav/grav-plugin-login/issues/45) +1. [](#bugfix) + * Correctly show an error message when the reset password form does not provide the correct nonce + # v2.0.0-rc.1 ## 06/01/2016 diff --git a/languages.yaml b/languages.yaml index fde85a4..6707920 100755 --- a/languages.yaml +++ b/languages.yaml @@ -85,7 +85,7 @@ en: REGISTRATION_DISABLED: "Registration disabled" USE_PARENT_ACL_LABEL: "Use parent access rules" USE_PARENT_ACL_HELP: "Check for parent access rules if no rules are defined" - PROTECT_PROTECTED_PAGE_ASSETS_LABEL: "Protect protected page assets" + PROTECT_PROTECTED_PAGE_ASSETS_LABEL: "Protect a login-protected page media" PROTECT_PROTECTED_PAGE_ASSETS_HELP: "If enabled, media of a login protected page is login protected as well and cannot be seen unless logged in" de: From 195f52be973fe9d47d19ee95161b4b157c57ef1a Mon Sep 17 00:00:00 2001 From: Quy Date: Sat, 18 Jun 2016 10:35:16 -0700 Subject: [PATCH 63/68] Fix keys (#82) - "assets" to "media" --- languages.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/languages.yaml b/languages.yaml index 6707920..1e2c540 100755 --- a/languages.yaml +++ b/languages.yaml @@ -85,8 +85,8 @@ en: REGISTRATION_DISABLED: "Registration disabled" USE_PARENT_ACL_LABEL: "Use parent access rules" USE_PARENT_ACL_HELP: "Check for parent access rules if no rules are defined" - PROTECT_PROTECTED_PAGE_ASSETS_LABEL: "Protect a login-protected page media" - PROTECT_PROTECTED_PAGE_ASSETS_HELP: "If enabled, media of a login protected page is login protected as well and cannot be seen unless logged in" + PROTECT_PROTECTED_PAGE_MEDIA_LABEL: "Protect a login-protected page media" + PROTECT_PROTECTED_PAGE_MEDIA_HELP: "If enabled, media of a login protected page is login protected as well and cannot be seen unless logged in" de: PLUGIN_LOGIN: From bb49c69a081b8a47dee0e2c891a1c766df7568f0 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Thevenet Date: Sun, 19 Jun 2016 09:56:17 -0400 Subject: [PATCH 64/68] :fr: updated + fix (#83) :fr: updated + single quote fix --- languages.yaml | 54 +++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/languages.yaml b/languages.yaml index 1e2c540..7752415 100755 --- a/languages.yaml +++ b/languages.yaml @@ -150,53 +150,53 @@ fr: BTN_SEND_INSTRUCTIONS: "Envoyer les instructions de Réinitialisation" RESET_LINK_EXPIRED: "Le lien de réinitialisation a expiré, veuillez réessayer" RESET_PASSWORD_RESET: "Le mot de passe a été réinitialisé" - RESET_INVALID_LINK: "Le lien de réinitialisation utilisé n'est pas valide, veuillez réessayer" + RESET_INVALID_LINK: "Le lien de réinitialisation utilisé n’est pas valide, veuillez réessayer" FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL: "Les instructions pour la réinitialisation de votre mot de passe ont été envoyées par e-mail à %s" FORGOT_FAILED_TO_EMAIL: "Impossible d’envoyer les instructions, veuillez réessayer ultérieurement" - FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL: "Impossible de réinitialiser le mot de passe pour %s, aucune adresse e-mail n'a été paramétrée" - FORGOT_USERNAME_DOES_NOT_EXIST: "L’utilisateur avec le nom d'utilisateur %s n’existe pas" + FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL: "Impossible de réinitialiser le mot de passe pour %s, aucune adresse e-mail n’a été paramétrée" + FORGOT_USERNAME_DOES_NOT_EXIST: "L’utilisateur avec le nom d’utilisateur %s n’existe pas" FORGOT_EMAIL_NOT_CONFIGURED: "Impossible de réinitialiser le mot de passe. Ce site n’est pas configuré pour envoyer des e-mails" FORGOT_EMAIL_SUBJECT: "Demande de réinitialisation de mot de passe %s" FORGOT_EMAIL_BODY: "

Réinitialisation de mot de passe

%1$s,

Une demande a été faite sur %4$s pour la réinitialisation de votre mot de passe.


Cliquez ici pour réinitialiser votre mot de passe

Vous pouvez également copier l’URL suivante dans la barre d’adresse de votre navigateur :

%2$s


Cordialement,

%3$s

" SESSION: "Session - “Se souvenir de moi”" REMEMBER_ME: "Se souvenir de moi" REMEMBER_ME_HELP: "Définit un cookie persistant sur votre navigateur autorisant l’authentification par connexion persistante entre les sessions." - REMEMBER_ME_STOLEN_COOKIE: "Quelqu’un d'autre a utilisé vos informations de connexion pour accéder à cette page ! Toutes les sessions ont été déconnectées. Veuillez vous connecter avec vos identifiants et vérifier vos données." + REMEMBER_ME_STOLEN_COOKIE: "Quelqu’un d’autre a utilisé vos informations de connexion pour accéder à cette page ! Toutes les sessions ont été déconnectées. Veuillez vous connecter avec vos identifiants et vérifier vos données." BUILTIN_CSS: "Utiliser les CSS intégrés" - BUILTIN_CSS_HELP: "Utiliser les CSS fournis dans le plugin d'administration" + BUILTIN_CSS_HELP: "Utiliser les CSS fournis dans le plugin d’administration" ROUTE: "Chemin de connexion" ROUTE_HELP: "Chemin personnalisé vers une page de connexion personnalisée proposée par votre thème" - ROUTE_REGISTER: "Chemin vers l'inscription" - ROUTE_REGISTER_HELP: "Chemin vers la page d’inscription. A définir si vous souhaitez utiliser la page d’inscription intégrée. Laisser vide si vous disposez de votre propre formulaire d'inscription." - USERNAME_NOT_VALID: "Le nom d’utilisateur doit comporter entre 3 et 16 caractères et peut être composé de lettres minuscules, de chiffres et de tirets de soulignement (underscores) et des traits d'union. Les lettres majuscules, les espaces et les caractères spéciaux ne sont pas autorisés." + ROUTE_REGISTER: "Chemin vers l’inscription" + ROUTE_REGISTER_HELP: "Chemin vers la page d’inscription. A définir si vous souhaitez utiliser la page d’inscription intégrée. Laisser vide si vous disposez de votre propre formulaire d’inscription." + USERNAME_NOT_VALID: "Le nom d’utilisateur doit comporter entre 3 et 16 caractères et peut être composé de lettres minuscules, de chiffres et de tirets de soulignement (underscores) et des traits d’union. Les lettres majuscules, les espaces et les caractères spéciaux ne sont pas autorisés." USERNAME_NOT_AVAILABLE: "Le nom d’utilisateur %s existe déjà, veuillez en choisir un autre." - PASSWORD_NOT_VALID: "Le mot de passe doit contenir au moins un chiffre, une majuscule et une minuscule et être composé d'au moins 8 caractères" + PASSWORD_NOT_VALID: "Le mot de passe doit contenir au moins un chiffre, une majuscule et une minuscule et être composé d’au moins 8 caractères" PASSWORDS_DO_NOT_MATCH: "Les mots de passe sont différents. Réessayez de saisir le même mot de passe deux fois." - EMAIL_NOT_CONFIGURED: "L'e-mail n'est pas configuré" - USER_NEEDS_EMAIL_FIELD: "L’utilisateur a besoin d'un champ pour e-mail" - EMAIL_SENDING_FAILURE: "Une erreur est survenue lors de l’envoi de l'e-mail." + EMAIL_NOT_CONFIGURED: "L’e-mail n’est pas configuré" + USER_NEEDS_EMAIL_FIELD: "L’utilisateur a besoin d’un champ pour e-mail" + EMAIL_SENDING_FAILURE: "Une erreur est survenue lors de l’envoi de l’e-mail." ACTIVATION_EMAIL_SUBJECT: "Activer votre compte sur %s" ACTIVATION_EMAIL_BODY: "Bonjour %s, cliquez pour activer votre compte sur %s" WELCOME_EMAIL_SUBJECT: "Bienvenue sur %s" WELCOME_EMAIL_BODY: "Bonjour %s, bienvenue sur %s!" NOTIFICATION_EMAIL_SUBJECT: "Nouvel utilisateur sur %s" - NOTIFICATION_EMAIL_BODY: "Bonjour, un nouvel utilisateur s'est inscrit sur %s. Nom d'utilisateur : %s, e-mail : %s" + NOTIFICATION_EMAIL_BODY: "Bonjour, un nouvel utilisateur s’est inscrit sur %s. Nom d’utilisateur : %s, e-mail : %s" EMAIL_FOOTER: "GetGrav.org" ACTIVATION_LINK_EXPIRED: "Le lien d’activation a expiré" USER_ACTIVATED_SUCCESSFULLY: "Utilisateur activé avec succès" INVALID_REQUEST: "Requête invalide" - USER_REGISTRATION: "Inscription de l'utilisateur" - USER_REGISTRATION_ENABLED_HELP: "Activer l'inscription des utilisateurs" + USER_REGISTRATION: "Inscription de l’utilisateur" + USER_REGISTRATION_ENABLED_HELP: "Activer l’inscription des utilisateurs" VALIDATE_PASSWORD1_AND_PASSWORD2: "Valider la double saisie du mot de passe" VALIDATE_PASSWORD1_AND_PASSWORD2_HELP: "Comparer et valider deux champs pour les mots de passe `Mot de passe 1` et `Mot de passe 2`. Activez cette option si vous avez deux champs de mots de passe dans le formulaire d’inscription." - SET_USER_DISABLED: "Définir l'utilisateur comme désactivé" - SET_USER_DISABLED_HELP: "La meilleure pratique si vous utilisez l’option `Envoyer un e-mail d’activation`. Ajoute l'utilisateur à Grav, mais le défini comme étant désactivé." + SET_USER_DISABLED: "Définir l’utilisateur comme désactivé" + SET_USER_DISABLED_HELP: "La meilleure pratique si vous utilisez l’option `Envoyer un e-mail d’activation`. Ajoute l’utilisateur à Grav, mais le défini comme étant désactivé." LOGIN_AFTER_REGISTRATION: "Connecte l’utilisateur après son inscription" - LOGIN_AFTER_REGISTRATION_HELP: "Identifier immédiatement l’utilisateur après l’inscription. Si l'e-mail d'activation est demandé, l’utilisateur sera connecté immédiatement après l'activation du compte." - SEND_ACTIVATION_EMAIL: "Envoyer un e-mail d'activation" - SEND_ACTIVATION_EMAIL_HELP: "Envoyer un e-mail à l’utilisateur pour l'activation son compte. Lorsque vous utilisez cette fonction, activez l’option `Définir l’utilisateur comme désactivé` afin que l’utilisateur soit désactivé et qu'un e-mail lui soit envoyé pour activer son compte." + LOGIN_AFTER_REGISTRATION_HELP: "Identifier immédiatement l’utilisateur après l’inscription. Si l’e-mail d’activation est demandé, l’utilisateur sera connecté immédiatement après l’activation du compte." + SEND_ACTIVATION_EMAIL: "Envoyer un e-mail d’activation" + SEND_ACTIVATION_EMAIL_HELP: "Envoyer un e-mail à l’utilisateur pour l’activation son compte. Lorsque vous utilisez cette fonction, activez l’option `Définir l’utilisateur comme désactivé` afin que l’utilisateur soit désactivé et qu’un e-mail lui soit envoyé pour activer son compte." SEND_NOTIFICATION_EMAIL: "Envoyer un e-mail de notification" - SEND_NOTIFICATION_EMAIL_HELP: "Informe l’administrateur du site qu'un nouvel utilisateur s’est enregistré. L'e-mail sera envoyé à la personne renseignée dans le champ `À` dans la configuration du plugin e-mail." + SEND_NOTIFICATION_EMAIL_HELP: "Informe l’administrateur du site qu’un nouvel utilisateur s’est enregistré. L’e-mail sera envoyé à la personne renseignée dans le champ `À` dans la configuration du plugin e-mail." SEND_WELCOME_EMAIL: "Envoyer un e-mail de bienvenue" SEND_WELCOME_EMAIL_HELP: "Envoyer un e-mail à un nouvel utilisateur enregistré." DEFAULT_VALUES: "Valeurs par défaut" @@ -212,14 +212,18 @@ fr: REDIRECT_AFTER_REGISTRATION_HELP: "Chemin personnalisé de redirection après l’inscription" OPTIONS: "Options" EMAIL_VALIDATION_MESSAGE: "Doit-être une adresse e-mail valide" - PASSWORD_VALIDATION_MESSAGE: "Le mot de passe doit-être composé d'au moins un chiffre, une majuscule et une minuscule, et au moins 8 caractères" - TIMEOUT_HELP: "Définit le délai d'expiration de la session en secondes lorsque 'Se souvenir de moi' est activé et coché par l’utilisateur. Minimum de 604800 ce qui correspond à 1 semaine." + PASSWORD_VALIDATION_MESSAGE: "Le mot de passe doit-être composé d’au moins un chiffre, une majuscule et une minuscule, et au moins 8 caractères" + TIMEOUT_HELP: "Définit le délai d’expiration de la session en secondes lorsque `Se souvenir de moi` est activé et coché par l’utilisateur. Minimum de 604800 ce qui correspond à 1 semaine." GROUPS_HELP: "Liste des groupes auxquels le nouvel utilisateur enregistré fera partie, le cas échéant." - SITE_ACCESS_HELP: "Liste des niveaux d'accès au site attribués au nouvel utilisateur enregistré. Exemple : `login` -> `true` " + SITE_ACCESS_HELP: "Liste des niveaux d’accès au site attribués au nouvel utilisateur enregistré. Exemple : `login` -> `true` " WELCOME: "Bienvenue" REDIRECT_AFTER_ACTIVATION: "Redirection après l’activation de l’utilisateur" - REDIRECT_AFTER_ACTIVATION_HELP: "Utilisé s’il est nécessaire pour l’utilisateur d'activer le compte par e-mail. Une fois activé, ce chemin s’affichera" + REDIRECT_AFTER_ACTIVATION_HELP: "Utilisé s’il est nécessaire pour l’utilisateur d’activer le compte par e-mail. Une fois activé, ce chemin s’affichera" REGISTRATION_DISABLED: "Inscription désactivée" + USE_PARENT_ACL_LABEL: "Appliquer les règles d’accès parentes" + USE_PARENT_ACL_HELP: "Utiliser les règles d’accès parentes si aucune règle n’a été définie" + PROTECT_PROTECTED_PAGE_MEDIA_LABEL: "Protéger le média d'une page par une protection par connexion" + PROTECT_PROTECTED_PAGE_MEDIA_HELP: "Si activé, les médias d'une page protégée par connexion sera également protégé par un système de connexion et ne pourra pas être visible à moins d'être connecté." hr: PLUGIN_LOGIN: From ae44820a67db86555bf7d36046c68b2e50816bba Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 21 Jun 2016 17:47:48 +0100 Subject: [PATCH 65/68] version update --- CHANGELOG.md | 4 +++- blueprints.yaml | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93e46a2..1175937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # v2.0.0-rc.2 -## 06/17/2016 +## 06/21/2016 1. [](#new) * Add an option to login protect a login-protected page media accessed through the page route [#45](https://github.com/getgrav/grav-plugin-login/issues/45) +1. [](#improved) + * Fixed some language keys 1. [](#bugfix) * Correctly show an error message when the reset password form does not provide the correct nonce diff --git a/blueprints.yaml b/blueprints.yaml index bf67358..1777e2a 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,5 +1,5 @@ name: Login -version: 2.0.0-rc.1 +version: 2.0.0-rc.2 testing: true description: Enables user authentication and login screen. icon: sign-in @@ -80,7 +80,7 @@ form: 0: PLUGIN_ADMIN.DISABLED validate: type: bool - + protect_protected_page_media: type: toggle label: PLUGIN_LOGIN.PROTECT_PROTECTED_PAGE_MEDIA_LABEL From 36ebc619328047afdf6523e4d96d0666e3b5f661 Mon Sep 17 00:00:00 2001 From: Tyler Cosgrove Date: Tue, 21 Jun 2016 16:47:03 -0400 Subject: [PATCH 66/68] Optimization of nonce creation --- login.php | 60 ++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/login.php b/login.php index 2e8be92..56cbff8 100755 --- a/login.php +++ b/login.php @@ -342,43 +342,39 @@ public function loginController() $post = !empty($_POST) ? $_POST : []; if (method_exists('Grav\Common\Utils', 'getNonce')) { - if ($task == 'login') { - if (!isset($post['login-form-nonce']) || !Utils::verifyNonce($post['login-form-nonce'], 'login-form')) { - $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), - 'error'); - $this->authenticated = false; - $twig = $this->grav['twig']; - $twig->twig_vars['notAuthorized'] = true; - - return; - } - } else { - if ($task == 'logout') { + switch ($task) { + case 'login': + if (!isset($post['login-form-nonce']) || !Utils::verifyNonce($post['login-form-nonce'], 'login-form')) { + $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), + 'info'); + $this->authenticated = false; + $twig = $this->grav['twig']; + $twig->twig_vars['notAuthorized'] = true; + + return; + } + break; + + case 'logout': $nonce = $this->grav['uri']->param('logout-nonce'); if (!isset($nonce) || !Utils::verifyNonce($nonce, 'logout-form')) { return; } - } else { - if ($task == 'forgot') { - if (!isset($post['forgot-form-nonce']) || !Utils::verifyNonce($post['forgot-form-nonce'], - 'forgot-form') - ) { - $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), - 'error'); - - return; - } - } else { - if ($task == 'reset') { - if (!isset($post['reset-form-nonce']) || !Utils::verifyNonce($post['reset-form-nonce'], - 'reset-form') - ) { - $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'error'); - return; - } - } + break; + + case 'forgot': + if (!isset($post['forgot-form-nonce']) || !Utils::verifyNonce($post['forgot-form-nonce'], 'forgot-form')) { + $this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'),'info'); + return; } - } + break; + + case 'reset': + if(!isset($post['reset-form-nonce']) || !Utils::verifyNonce($post['reset-form-nonce'], 'reset-form')) { + //$this->grav['messages']->add($this->grav['language']->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'info'); + //return; + } + break; } } From 8c471b43997b482a11aa022af0d7da017fb02340 Mon Sep 17 00:00:00 2001 From: Andrew Koebbe Date: Mon, 4 Jul 2016 07:17:48 -0500 Subject: [PATCH 67/68] Point account path to core's account stream (#85) --- classes/Login.php | 2 +- cli/ChangePasswordCommand.php | 6 +++--- cli/ChangeUserStateCommand.php | 6 +++--- cli/NewUserCommand.php | 4 ++-- login.php | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/classes/Login.php b/classes/Login.php index abedab7..2aa2f15 100755 --- a/classes/Login.php +++ b/classes/Login.php @@ -155,7 +155,7 @@ public function register($data) } $username = $data['username']; - $file = CompiledYamlFile::instance($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT, + $file = CompiledYamlFile::instance($this->grav['locator']->findResource('account://' . $username . YAML_EXT, true, true)); // Create user object and save it diff --git a/cli/ChangePasswordCommand.php b/cli/ChangePasswordCommand.php index 1fc8604..d15abb7 100644 --- a/cli/ChangePasswordCommand.php +++ b/cli/ChangePasswordCommand.php @@ -97,7 +97,7 @@ protected function serve() $username = strtolower($username); // Grab the account file and read in the information before setting the file (prevent setting erase) - $oldUserFile = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $oldUserFile = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('account://' . $username . YAML_EXT, true, true)); $oldData = $oldUserFile->content(); //Set the password feild to new password @@ -105,7 +105,7 @@ protected function serve() // Create user object and save it using oldData (with updated password) $user = new User($oldData); - $file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('account://' . $username . YAML_EXT, true, true)); $user->file($file); $user->save(); @@ -137,7 +137,7 @@ protected function validate($type, $value, $extra = '') if (!preg_match('/^[a-z0-9_-]{3,16}$/', $value)) { throw new \RuntimeException('Username should be between 3 and 16 characters, including lowercase letters, numbers, underscores, and hyphens. Uppercase letters, spaces, and special characters are not allowed'); } - if (!file_exists(self::getGrav()['locator']->findResource('user://accounts/' . $value . YAML_EXT))) { + if (!file_exists(self::getGrav()['locator']->findResource('account://' . $value . YAML_EXT))) { throw new \RuntimeException('Username "' . $value . '" does not exist, please pick another username'); } diff --git a/cli/ChangeUserStateCommand.php b/cli/ChangeUserStateCommand.php index a14b639..40f9dc6 100644 --- a/cli/ChangeUserStateCommand.php +++ b/cli/ChangeUserStateCommand.php @@ -96,7 +96,7 @@ protected function serve() $username = strtolower($username); // Grab the account file and read in the information before setting the file (prevent setting erase) - $oldUserFile = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $oldUserFile = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('account://' . $username . YAML_EXT, true, true)); $oldData = $oldUserFile->content(); //Set the state feild to new state @@ -104,7 +104,7 @@ protected function serve() // Create user object and save it using oldData (with updated state) $user = new User($oldData); - $file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('account://' . $username . YAML_EXT, true, true)); $user->file($file); $user->save(); @@ -136,7 +136,7 @@ protected function validate($type, $value, $extra = '') if (!preg_match('/^[a-z0-9_-]{3,16}$/', $value)) { throw new \RuntimeException('Username should be between 3 and 16 characters, including lowercase letters, numbers, underscores, and hyphens. Uppercase letters, spaces, and special characters are not allowed'); } - if (!file_exists(self::getGrav()['locator']->findResource('user://accounts/' . $value . YAML_EXT))) { + if (!file_exists(self::getGrav()['locator']->findResource('account://' . $value . YAML_EXT))) { throw new \RuntimeException('Username "' . $value . '" does not exist, please pick another username'); } diff --git a/cli/NewUserCommand.php b/cli/NewUserCommand.php index a0e479a..17dbf48 100644 --- a/cli/NewUserCommand.php +++ b/cli/NewUserCommand.php @@ -208,7 +208,7 @@ protected function serve() // Create user object and save it $user = new User($data); - $file = CompiledYamlFile::instance(Grav::instance()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true)); + $file = CompiledYamlFile::instance(Grav::instance()['locator']->findResource('account://' . $username . YAML_EXT, true, true)); $user->file($file); $user->save(); @@ -240,7 +240,7 @@ protected function validate($type, $value, $extra = '') if (!preg_match('/^[a-z0-9_-]{3,16}$/', $value)) { throw new \RuntimeException('Username should be between 3 and 16 characters, including lowercase letters, numbers, underscores, and hyphens. Uppercase letters, spaces, and special characters are not allowed'); } - if (file_exists(Grav::instance()['locator']->findResource('user://accounts/' . $value . YAML_EXT))) { + if (file_exists(Grav::instance()['locator']->findResource('account://' . $value . YAML_EXT))) { throw new \RuntimeException('Username "' . $value . '" already exists, please pick another username'); } diff --git a/login.php b/login.php index 56cbff8..1a9a673 100755 --- a/login.php +++ b/login.php @@ -544,7 +544,7 @@ private function processUserRegistration($form, Event $event) $username = $form->value('username'); $data['username'] = $username; - if (file_exists($this->grav['locator']->findResource('user://accounts/' . $username . YAML_EXT))) { + if (file_exists($this->grav['locator']->findResource('account://' . $username . YAML_EXT))) { $this->grav->fireEvent('onFormValidationError', new Event([ 'form' => $form, 'message' => $this->grav['language']->translate([ From 1439701075b2b6cecf81b627423a6eac06842b7a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 14 Jul 2016 11:51:58 -0600 Subject: [PATCH 68/68] version update --- CHANGELOG.md | 7 +++++++ blueprints.yaml | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1175937..fe1ab8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v2.0.0 +## 07/14/2016 + +1. [](#improved) + * Optimized nonce creation + * Point account path to core's account stream [#85](https://github.com/getgrav/grav-plugin-login/issues/85) + # v2.0.0-rc.2 ## 06/21/2016 diff --git a/blueprints.yaml b/blueprints.yaml index 1777e2a..fe5f9a0 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,6 +1,5 @@ name: Login -version: 2.0.0-rc.2 -testing: true +version: 2.0.0 description: Enables user authentication and login screen. icon: sign-in author: