diff options
author | Alexander Sulfrian <alex@spline.inf.fu-berlin.de> | 2015-04-09 17:33:22 +0200 |
---|---|---|
committer | Alexander Sulfrian <alex@spline.inf.fu-berlin.de> | 2015-04-09 17:33:22 +0200 |
commit | a28626a0824fd81433b55181361948fb40977aec (patch) | |
tree | fdfcd005c5c2fd23e1d7b74dddfac4f5a111fa1f | |
download | laravel-a28626a0824fd81433b55181361948fb40977aec.tar.gz laravel-a28626a0824fd81433b55181361948fb40977aec.tar.bz2 laravel-a28626a0824fd81433b55181361948fb40977aec.zip |
Initial commit
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | composer.json | 9 | ||||
-rw-r--r-- | src/Console/Commands/SyncSplineAccountsCommand.php | 124 | ||||
-rw-r--r-- | src/Hashing/HashServiceProvider.php | 34 | ||||
-rw-r--r-- | src/Hashing/SplineHasher.php | 60 | ||||
-rw-r--r-- | src/Models/User.php | 16 | ||||
-rw-r--r-- | src/Providers/ConsoleServiceProvider.php | 31 |
7 files changed, 277 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..99847a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Laravel +bootstrap/compiled.php +vendor diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..a2d9eb4 --- /dev/null +++ b/composer.json @@ -0,0 +1,9 @@ +{ + "name": "spline-cachet", + "description": "Spline extensions for cachet (open source status page in PHP).", + "autoload": { + "psr-4": { + "Spline\\Cachet\\": "src/" + } + } +} diff --git a/src/Console/Commands/SyncSplineAccountsCommand.php b/src/Console/Commands/SyncSplineAccountsCommand.php new file mode 100644 index 0000000..a83a73a --- /dev/null +++ b/src/Console/Commands/SyncSplineAccountsCommand.php @@ -0,0 +1,124 @@ +<?php + +namespace Spline\Cachet\Console\Commands; + +use Illuminate\Console\Command; +use Symfony\Component\Console\Input\InputArgument; +use Spline\Cachet\Models\User; + +class SyncSplineAccountsCommand extends Command { + + protected $name = 'cachet:sync-spline'; + protected $description = 'Sync the spline user into the laravel backend.'; + + protected function get_all_users() + { + $users = array(); + foreach (User::all() as $user) { + if (ends_with($user->email, '@spline.de')) { + $users[$user->email] = $user; + } + } + $this->comment('Found ' . count($users) . ' existing users.'); + + return $users; + } + + protected function create_new_user($username, $email, $passwd) + { + $this->output->writeln("Creating new user: <info>$email</info>"); + $u = new User; + $u->username = $username; + $u->email = $email; + $u->setCryptedPassword($passwd); + $u->save(); + } + + protected function update_user($user, $passwd) + { + $this->output->writeln('Updating user: <info>' . $user->email . '</info>'); + $user->setCryptedPassword($passwd); + $user->save(); + } + + protected function remove_users($users) + { + if (count($users) == 0) + return; + + if (count($users) == 1) { + $this->comment(count($users) . ' user is outdated.'); + } + else { + $this->comment(count($users) . ' users are outdated.'); + } + + foreach ($users as $uid => $user) { + $this->output->writeln("Deleting user: <info>$uid</info>"); + $user->delete(); + } + } + + protected function parse_input($input, $handler) + { + $fh = @fopen($input, 'r'); + if (!$fh) { + $this->error('Could not open input file.'); + return 1; + } + + while (($buffer = fgets($fh)) !== false) { + $buffer = trim($buffer); + if ($buffer == '' || $buffer[0] == '#' || strpos($buffer, ' ') === false) { + continue; + } + + list($username, $passwd) = explode(' ', $buffer, 2); + $handler($username, $passwd); + } + + if (!feof($fh)) { + $this->error('Unexpected fgets() fail.'); + return 1; + } + + fclose($fh); + return 0; + } + + public function fire() + { + $input = $this->argument('FILE'); + $users = $this->get_all_users(); + + $ret = $this->parse_input($input, function ($username, $passwd) use (&$users) { + $email = $username . '@spline.de'; + + if (array_key_exists($email, $users)) { + $u = $users[$email]; + unset($users[$email]); + + if ($u->password != $passwd) { + $this->update_user($u, $passwd); + } + } + else { + $this->create_new_user($username, $email, $passwd); + } + }); + + if ($ret != 0) { + return $ret; + } + + $this->remove_users($users); + return 0; + } + + protected function getArguments() + { + return array( + array('FILE', InputArgument::REQUIRED, 'Input file with users and password hashes.'), + ); + } +} diff --git a/src/Hashing/HashServiceProvider.php b/src/Hashing/HashServiceProvider.php new file mode 100644 index 0000000..e634de7 --- /dev/null +++ b/src/Hashing/HashServiceProvider.php @@ -0,0 +1,34 @@ +<?php namespace Spline\Cachet\Hashing;
+
+use Illuminate\Support\ServiceProvider;
+
+class HashServiceProvider extends ServiceProvider {
+
+ /**
+ * Indicates if loading of the provider is deferred.
+ *
+ * @var bool
+ */
+ protected $defer = true;
+
+ /**
+ * Register the service provider.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ $this->app->bindShared('hash', function() { return new SplineHasher; });
+ }
+
+ /**
+ * Get the services provided by the provider.
+ *
+ * @return array
+ */
+ public function provides()
+ {
+ return array('hash');
+ }
+
+}
diff --git a/src/Hashing/SplineHasher.php b/src/Hashing/SplineHasher.php new file mode 100644 index 0000000..bf5d0d6 --- /dev/null +++ b/src/Hashing/SplineHasher.php @@ -0,0 +1,60 @@ +<?php namespace Spline\Cachet\Hashing; + +use Illuminate\Hashing\BcryptHasher; + +class SplineHasher extends BcryptHasher { + + /** + * Check the given plain value against a hash. + * + * @param string $value + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function check($value, $hashedValue, array $options = array()) + { + if (starts_with($hashedValue, '{')) { + if (starts_with($hashedValue, '{SSHA}')) { + $hash = base64_decode(substr($hashedValue, 6)); + $salt = substr($hash, 20); + if ((pack("H*", sha1($value.$salt)).$salt) == $hash) { + return true; + } + } + elseif (starts_with($hashedValue, '{SMD5}')) { + $hash = base64_decode(substr($hashedValue, 6)); + $salt = substr($hash, 16); + if ((md5($value.$salt, true).$salt) == $hash) { + return true; + } + } + elseif (starts_with(strtolower($hashedValue), '{crypt}')) { + $hash = substr($hashedValue, 7); + if (password_verify($value, $hash)) { + return true; + } + } + + return false; + } + + return parent::check($value, $hashedValue, $options); + } + + /** + * Check if the given hash has been hashed using the given options. + * + * @param string $hashedValue + * @param array $options + * @return bool + */ + public function needsRehash($hashedValue, array $options = array()) + { + if (starts_with($hashedValue, '{')) { + return false; + } + + return parent::needsRehash($hashedValue, $options); + } +} diff --git a/src/Models/User.php b/src/Models/User.php new file mode 100644 index 0000000..a978399 --- /dev/null +++ b/src/Models/User.php @@ -0,0 +1,16 @@ +<?php + +namespace Spline\Cachet\Models; + +use CachetHQ\Cachet\Models\User as BaseUser; + +class User extends BaseUser +{ + public function setCryptedPassword($password) + { + $this->attributes['password'] = $password; + + return $this; + } +} + diff --git a/src/Providers/ConsoleServiceProvider.php b/src/Providers/ConsoleServiceProvider.php new file mode 100644 index 0000000..559dfaa --- /dev/null +++ b/src/Providers/ConsoleServiceProvider.php @@ -0,0 +1,31 @@ +<?php + +namespace Spline\Cachet\Providers; + +use Illuminate\Support\ServiceProvider; +use Spline\Cachet\Console\Commands\SyncSplineAccountsCommand; + +class ConsoleServiceProvider extends ServiceProvider +{ + /** + * Boot the service provider. + * + * @return void + */ + public function boot() + { + $this->commands('Spline\Cachet\Console\Commands\SyncSplineAccountsCommand'); + } + + /** + * Register the service provider. + * + * @return void + */ + public function register() + { + $this->app->singleton('Spline\Cachet\Console\Commands\SyncSplineAccountsCommand', function ($app) { + return new SyncSplineAccountsCommand(); + }); + } +} |