summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alex@spline.inf.fu-berlin.de>2015-04-09 17:33:22 +0200
committerAlexander Sulfrian <alex@spline.inf.fu-berlin.de>2015-04-09 17:33:22 +0200
commita28626a0824fd81433b55181361948fb40977aec (patch)
treefdfcd005c5c2fd23e1d7b74dddfac4f5a111fa1f
downloadlaravel-a28626a0824fd81433b55181361948fb40977aec.tar.gz
laravel-a28626a0824fd81433b55181361948fb40977aec.tar.bz2
laravel-a28626a0824fd81433b55181361948fb40977aec.zip
Initial commit
-rw-r--r--.gitignore3
-rw-r--r--composer.json9
-rw-r--r--src/Console/Commands/SyncSplineAccountsCommand.php124
-rw-r--r--src/Hashing/HashServiceProvider.php34
-rw-r--r--src/Hashing/SplineHasher.php60
-rw-r--r--src/Models/User.php16
-rw-r--r--src/Providers/ConsoleServiceProvider.php31
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();
+ });
+ }
+}