summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md36
-rw-r--r--composer.json5
-rw-r--r--src/Jasny/Auth.php (renamed from src/Auth.php)84
-rw-r--r--src/Jasny/Auth/User.php (renamed from src/Auth/User.php)14
-rw-r--r--src/Jasny/Auth/byGroup.php81
-rw-r--r--src/Jasny/Auth/byLevel.php74
6 files changed, 206 insertions, 88 deletions
diff --git a/README.md b/README.md
index 1552aba..1d549c8 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ Installation
Install using composer
- composer require jasny\auth
+ composer require jasny\auth
Setup
@@ -155,34 +155,40 @@ Check if user is allowed to do something
Get a verification hash. Use it in an url and set that url in an e-mail to the user
- // Create a new $user
+```php
+// Create a new $user
- $confirmHash = generateConfirmationHash($user);
- $url = 'http://' . $_SERVER['HTTP_HOST'] . '/confirm.php?hash=' . $hash;
+$confirmHash = generateConfirmationHash($user);
+$url = 'http://' . $_SERVER['HTTP_HOST'] . '/confirm.php?hash=' . $hash;
- // send email with $url to $user
+// send email with $url to $user
+```
Use the confirmation hash to fetch and verify the user
- // --- confirm.php
+```php
+// --- confirm.php
- $user = Auth::fetchForConfirmation($_GET['hash']);
-
+$user = Auth::fetchForConfirmation($_GET['hash']);
+```
### Forgot password
Forgot password works the same as the signup confirmation.
- // Fetch $user by e-mail
+```php
+// Fetch $user by e-mail
- $confirmHash = generatePasswordResetHash($user);
- $url = 'http://' . $_SERVER['HTTP_HOST'] . '/reset.php?hash=' . $hash;
+$confirmHash = generatePasswordResetHash($user);
+$url = 'http://' . $_SERVER['HTTP_HOST'] . '/reset.php?hash=' . $hash;
- // send email with $url to $user
+// send email with $url to $user
+```
Use the confirmation hash to fetch and verify the user
- // --- reset.php
+```php
+// --- reset.php
- $user = Auth::fetchForPasswordReset($_GET['hash']);
-
+$user = Auth::fetchForPasswordReset($_GET['hash']);
+```
diff --git a/composer.json b/composer.json
index ec9e869..89a9339 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,5 @@
{
"name": "jasny/auth",
- "bin": ["bin/auth"],
"description": "Authentication and level based authorization",
"keywords": ["auth"],
"license": "MIT",
@@ -20,8 +19,8 @@
"php": ">=5.4.0"
},
"autoload": {
- "psr-4": {
- "Jasny\\": "src/"
+ "psr-0": {
+ "Jasny\\Auth": "src/"
}
}
}
diff --git a/src/Auth.php b/src/Jasny/Auth.php
index f07715e..2322301 100644
--- a/src/Auth.php
+++ b/src/Jasny/Auth.php
@@ -5,20 +5,11 @@ namespace Jasny;
use Jasny\Auth\User;
/**
- * Authenticate and authorize
+ * Authentication
*/
abstract class Auth
{
/**
- * Authorization levels
- * @var array
- */
- protected static $levels = [
- 1 => 'user',
- 1000 => 'admin'
- ];
-
- /**
* Secret word for creating a verification hash
* @var string
*/
@@ -49,58 +40,6 @@ abstract class Auth
/**
- * Get secret word
- *
- * @return string
- */
- protected static function getSecret()
- {
- if (!isset(static::$secret)) throw new \Exception("Auth secret isn't set");
- return static::$secret;
- }
-
-
- /**
- * Get all auth levels
- *
- * @return array
- */
- public static function getLevels()
- {
- return static::$levels;
- }
-
- /**
- * Get auth level
- *
- * @param string $type
- * @return int
- */
- public static function getLevel($type)
- {
- $level = array_search($type, static::$levels);
- if ($level === false) throw new \Exception("Authorization level '$type' isn't defined.");
-
- return $level;
- }
-
- /**
- * Check if user has specified auth level or more.
- *
- * @param int $level
- * @return boolean
- */
- public static function forLevel($level)
- {
- if ($level === 0) return true;
- if (!self::user()) return false;
-
- if (is_string($level) && !ctype_digit($level)) $level = static::getLevel($type);
- return self::user()->getAuthLevel() >= $level;
- }
-
-
- /**
* Generate a password
*
* @param string $password
@@ -123,7 +62,7 @@ abstract class Auth
$user = static::fetchUserByUsername($username);
if (!isset($user) || $user->getPassword() !== self::password($password, $user->getPassword())) return false;
- static::setUser($user);
+ return static::setUser($user);
}
/**
@@ -132,7 +71,7 @@ abstract class Auth
public static function logout()
{
self::$user = null;
- unset($_SESSION['auth_user_id']);
+ unset($_SESSION['auth_uid']);
}
@@ -147,7 +86,7 @@ abstract class Auth
if (!$user->onLogin()) return false;
self::$user = $user;
- $_SESSION['auth_user_id'] = $user->getId();
+ $_SESSION['auth_uid'] = $user->getId();
return true;
}
@@ -158,8 +97,8 @@ abstract class Auth
*/
public static function user()
{
- if (!isset(self::$user) && isset($_SESSION['auth_user_id'])) {
- self::$user = static::fetchUserById($_SESSION['auth_user_id']);
+ if (!isset(self::$user) && isset($_SESSION['auth_uid'])) {
+ self::$user = static::fetchUserById($_SESSION['auth_uid']);
}
return self::$user;
@@ -167,6 +106,17 @@ abstract class Auth
/**
+ * Get secret word
+ *
+ * @return string
+ */
+ protected static function getSecret()
+ {
+ if (!isset(static::$secret)) throw new \Exception("Auth secret isn't set");
+ return static::$secret;
+ }
+
+ /**
* Generate a confirmation hash
*
* @param User $user
diff --git a/src/Auth/User.php b/src/Jasny/Auth/User.php
index 3606f07..8e82072 100644
--- a/src/Auth/User.php
+++ b/src/Jasny/Auth/User.php
@@ -29,11 +29,14 @@ interface User
public function getPassword();
/**
- * Get authentication level
+ * Get authentication level or group(s).
*
- * @return int
+ * @internal Return level (int) or level name (string) for level based auth.
+ * @internal Return group (string) or groups (array) for group base auth.
+ *
+ * @return int|string|array
*/
- public function getAuthLevel();
+ public function getRole();
/**
@@ -42,4 +45,9 @@ interface User
* @return boolean false cancels the login
*/
public function onLogin();
+
+ /**
+ * Event called on logout.
+ */
+ public function onLogout();
}
diff --git a/src/Jasny/Auth/byGroup.php b/src/Jasny/Auth/byGroup.php
new file mode 100644
index 0000000..2fd5c54
--- /dev/null
+++ b/src/Jasny/Auth/byGroup.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Jasny\Auth;
+
+/**
+ * Authorize by access group.
+ * Can be used for ACL (Access Control List).
+ */
+trait byGroup
+{
+ /**
+ * Authorization groups and each group is embodies.
+ *
+ * <code>
+ * protected static $groups = [
+ * 'user' => [],
+ * 'developer' => ['user'],
+ * 'accountant' => ['user'],
+ * 'admin' => ['developer', 'accountant']
+ * ];
+ * </code>
+ *
+ * @var array
+ */
+ protected static $groups;
+
+
+ /**
+ * Get all auth groups
+ *
+ * @return array
+ */
+ public static function getGroups()
+ {
+ if (!isset(static::$groups)) {
+ trigger_error("Auth groups aren't set", E_USER_WARNING);
+ return [];
+ }
+
+ return static::$groups;
+ }
+
+ /**
+ * Get group and all groups it embodies.
+ *
+ * @return array
+ */
+ public static function expandGroup($group)
+ {
+ $groups = [$group];
+
+ if (!empty(self::$groups[$group])) {
+ foreach (self::$groups[$group] as $sub) {
+ $groups = array_merge($groups, static::expandGroup($sub));
+ }
+
+ $groups = array_unique($groups);
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Check if user is in specified access group.
+ *
+ * @param int $group
+ * @return boolean
+ */
+ public static function authorize($group)
+ {
+ if (!self::user()) return false;
+
+ $roles = self::user()->getRole();
+
+ foreach ($roles as $role) {
+ $roles = array_merge($roles, self::expandGroup($role));
+ }
+
+ return in_array($group, $roles);
+ }
+}
diff --git a/src/Jasny/Auth/byLevel.php b/src/Jasny/Auth/byLevel.php
new file mode 100644
index 0000000..521cbae
--- /dev/null
+++ b/src/Jasny/Auth/byLevel.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Jasny\Auth;
+
+/**
+ * Authorize by access level.
+ */
+trait byLevel
+{
+ /**
+ * Authorization levels.
+ * Level names should not contain only digits.
+ *
+ * <code>
+ * protected static $groups = [
+ * 'user' => 1,
+ * 'moderator' => 100,
+ * 'admin' => 1000
+ * ];
+ * </code>
+ *
+ * @var array
+ */
+ protected static $levels;
+
+
+ /**
+ * Get all access levels.
+ *
+ * @return array
+ */
+ public static function getLevels()
+ {
+ if (!isset(static::$levels)) {
+ trigger_error("Auth levels aren't set", E_USER_WARNING);
+ return [];
+ }
+
+ return static::$levels;
+ }
+
+ /**
+ * Get access level
+ *
+ * @param string $name Level name
+ * @return int
+ */
+ public static function getLevel($name)
+ {
+ $levels = static::getLevels();
+ if (!isset($levels[$name])) throw new \Exception("Authorization level '$name' isn't defined.");
+
+ return $levels[$name];
+ }
+
+ /**
+ * Check if user has specified access level or more.
+ *
+ * @param int|string $level
+ * @return boolean
+ */
+ public static function authorize($level)
+ {
+ if ($level === 0) return true;
+ if (!static::user()) return false;
+
+ if (is_string($level) && !ctype_digit($level)) $level = static::getLevel($level);
+
+ $role = static::user()->getRole();
+ if (is_string($role) && !ctype_digit($role)) $role = static::getLevel($role);
+
+ return $role >= $level;
+ }
+}