]> git.andy128k.dev Git - ipf.git/commitdiff
rework auth app
authorAndrey Kutejko <andy128k@gmail.com>
Sun, 14 Sep 2014 08:18:59 +0000 (11:18 +0300)
committerAndrey Kutejko <andy128k@gmail.com>
Sun, 14 Sep 2014 08:18:59 +0000 (11:18 +0300)
ipf/admin/forms/login.php
ipf/admin/views.php
ipf/auth/admin.php
ipf/auth/app.php
ipf/auth/commands/createsuperuser.php
ipf/auth/middleware.php
ipf/auth/models.php
ipf/form/objectform.php [new file with mode: 0644]

index ef950e46888f9f4cb9f9d09fae80622cdb82a48f..b05b32f8a48e429befea93cd4515ce8404a49a2c 100644 (file)
@@ -16,10 +16,11 @@ class IPF_Admin_Forms_Login extends IPF_Form
     {
         $data = parent::clean();
 
-        $this->user = User::checkCreditentials($data['username'], $data['password']);
-        if (!$this->user)
+        $user = \PFF\Container::auth()->findUserByUsername($data['username']);
+        if (!$user || !$user->checkPassword($data['password']))
             throw new IPF_Exception_Form(__('The login or the password is not valid. The login and the password are case sensitive.'));
 
+        $this->user = $user;
         return $data;
     }
 
index b23a56195db2c9c757c0df1c2e17be5ea5989b05..d1bb7c8cf7c5b7a88ae749056d9aace169645580 100644 (file)
@@ -87,7 +87,7 @@ function IPF_Admin_Views_Login($request, $match)
     if ($request->method == 'POST') {
         $form = new IPF_Admin_Forms_Login($request->POST);
         if ($form->isValid()) {
-            IPF_Auth_App::login($request, $form->user);
+            \PFF\Container::auth()->login($request, $form->user);
             return new IPF_HTTP_Response_Redirect($success_url);
         }
     } else {
@@ -104,7 +104,7 @@ function IPF_Admin_Views_Login($request, $match)
 
 function IPF_Admin_Views_Logout($request, $match)
 {
-    IPF_Auth_App::logout($request);
+    \PFF\Container::auth()->logout($request);
     $context = array(
        'page_title' => IPF::get('admin_title'),
     );
@@ -120,10 +120,10 @@ function IPF_Admin_Views_Impersonate($request, $match)
         $success_url = IPF_HTTP_URL::urlForView('IPF_Admin_Views_Index');
 
     if (!$request->user->isAnonymous() && $request->user->is_superuser) {
-        $user = User::find($match[1]);
+        $user = \PFF\Container::auth()->findUser($match[1]);
         if (!$user)
             return new IPF_HTTP_Response_NotFound($request);
-        IPF_Auth_App::login($request, $user);
+        \PFF\Container::auth()->login($request, $user);
     }
 
     return new IPF_HTTP_Response_Redirect($success_url);
index b80e9845e85d56cf76ae014a2358ffbcd054b6f8..e45bb744e86b71430c004e470e2a29b2f6131e8e 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use \PFF\HtmlBuilder\Text as Text;
+
 function permissionChoices()
 {
     $choices = array();
@@ -18,7 +20,7 @@ function permissionChoices()
     return $choices;
 }
 
-class IPFAuthAdminUserForm extends IPF_Form
+class IPFAuthAdminUserForm extends IPF_ObjectForm
 {
     private $isAdd;
 
@@ -111,9 +113,16 @@ class IPFAuthAdminUserForm extends IPF_Form
 
 class AdminUser extends IPF_Admin_Component
 {
+    private $auth_app;
+
+    function __construct()
+    {
+        $this->auth_app = \PFF\Container::auth();
+    }
+
     public function getItems($searchValue, $filters, $page, $pageSize)
     {
-        return User::query()
+        return $this->auth_app->userQuery()
             ->limit($pageSize)
             ->offset(($page - 1) * $pageSize)
             ->fetchAll('id');
@@ -121,7 +130,7 @@ class AdminUser extends IPF_Admin_Component
 
     public function itemsCount($searchValue, $filters)
     {
-        return User::query()
+        return $this->auth_app->userQuery()
             ->select(null)->select('COUNT(1)')
             ->fetchColumn();
     }
@@ -168,7 +177,7 @@ class AdminUser extends IPF_Admin_Component
 
     public function getObjectByID($id)
     {
-        return User::query()->where('id', $id)->fetch();
+        return \PFF\Container::auth()->findUser($id);
     }
 
     protected function _getForm($user, $data)
@@ -176,11 +185,6 @@ class AdminUser extends IPF_Admin_Component
         $extra = array();
         if ($user) {
             $extra['initial'] = array(
-                'username' => $user->username,
-                'email' => $user->email,
-                'is_active' => $user->is_active,
-                'is_staff' => $user->is_staff,
-                'is_superuser' => $user->is_superuser,
                 'permissions' => \PFF\Arr::create($user->permissions())->pluck('id')->arr(),
                 'roles' => \PFF\Arr::create($user->roles())->pluck('id')->arr(),
             );
@@ -188,49 +192,27 @@ class AdminUser extends IPF_Admin_Component
         } else {
             $extra['is_add'] = true;
         }
-        return new IPFAuthAdminUserForm($data, $extra);
+        return new IPFAuthAdminUserForm($data, $user, $extra);
     }
 
     public function saveObject($form, $user)
     {
         if (!$user)
-            $user = new User;
-
-        if ($user->id) {
-        } else {
-        }
-
-/*  
-
-//            $this->cleaned_data['password'] = User::SetPassword2($this->cleaned_data['password1']);
-
-
-
-        \PFF\Container::databaseQuery()
-            ->deleteFrom('auth_user_permission')
-            ->where('user_id', $user->id)
-            ->execute();
-
-        $query = \PFF\Container::databaseQuery()
-            ->insertInto('auth_user_permission');
-        foreach ($this->cleaned_data['permissions'] as $pid)
-            $query->values(array('user_id' => $user->id, 'permission_id' => $pid));
-        $query->execute();
+            $user = $this->auth_app->createUser();
 
+        $form->toObject($user);
+        if ($form->cleaned_data['password1'])
+            $user->setPassword($form->cleaned_data['password1']);
+        $user->save();
 
-        \PFF\Container::databaseQuery()
-            ->deleteFrom('auth_user_group')
-            ->where('user_id', $user->id)
-            ->execute();
+        Permission::revokeAll($user);
+        $permissions = Permission::query()->where('id', $form->cleaned_data['permissions'])->fetchAll();
+        Permission::grantAll($permissions, $user);
 
-        $query = \PFF\Container::databaseQuery()
-            ->insertInto('auth_user_role');
-        foreach ($this->cleaned_data['roles'] as $pid)
-            $query->values(array('user_id' => $user->id, 'role_id' => $pid));
-        $query->execute();
+        Role::leaveAll($user);
+        foreach (Role::query()->where('id', $form->cleaned_data['roles']) as $role)
+            $role->join($user);
 
-
-    */
         return array($user->id, $user);
     }
 
@@ -249,10 +231,10 @@ class AdminUser extends IPF_Admin_Component
         );
     }
 
-    public function verbose_name() { return 'User'; }
+    public function verbose_name() { return __('User'); }
 }
 
-class IPFAdminRoleForm extends IPF_Form
+class IPFAdminRoleForm extends IPF_ObjectForm
 {
     function initFields($extra=array())
     {
@@ -316,14 +298,12 @@ class AdminRole extends IPF_Admin_Component
 
     protected function _getForm($role, $data)
     {
-        $extra = array();
-        if ($role) {
-            $extra['initial'] = array(
-                'name' => $role->name,
+        if ($role)
+            return new IPFAdminRoleForm($data, $role, array('initial' => array(
                 'permissions' => \PFF\Arr::create($role->permissions())->pluck('id')->arr(),
-            );
-        }
-        return new IPFAdminRoleForm($data, $extra);
+            )));
+        else
+            return new IPFAdminRoleForm($data, null);
     }
 
     public function saveObject($form, $role)
@@ -331,34 +311,12 @@ class AdminRole extends IPF_Admin_Component
         if (!$role)
             $role = new Role;
 
-        $role->name = $form->cleaned_data['name'];
-        if ($role->id) {
-            \PFF\Container::databaseQuery()
-                ->update('auth_role')
-                ->set('name', $role->name)
-                ->where('id', $role->id)
-                ->execute();
-
-            \PFF\Container::databaseQuery()
-                ->deleteFrom('auth_role_permission')
-                ->where('role_id', $role->id)
-                ->execute();
-        } else {
-            $role->id = \PFF\Container::databaseQuery()
-                ->insertInto('auth_role')
-                ->values(array('name' => $role->name))
-                ->execute();
-        }
-
-        if ($form->cleaned_data['permissions']) {
-            $data = array_map(function($pid) use($role) { return array('role_id' => $role->id, 'permission_id' => $pid); },
-                $form->cleaned_data['permissions']);
+        $form->toObject($role);
+        $role->save();
 
-            \PFF\Container::databaseQuery()
-                ->insertInto('auth_role_permission')
-                ->values($data)
-                ->execute();
-        }
+        Permission::revokeAll($role);
+        foreach (Permission::query()->where('id', $form->cleaned_data['permissions']) as $permission)
+            $permission->grant($role);
 
         return array($role->id, $role);
     }
@@ -371,8 +329,8 @@ class AdminRole extends IPF_Admin_Component
             ->execute();
     }
 
-    public function page_title()   { return 'Group'; }
-    public function verbose_name() { return 'Group'; }
+    public function page_title()   { return __('Role'); }
+    public function verbose_name() { return __('Role'); }
 }
 
 if (IPF_Auth_App::ArePermissionsEnabled()) {
index f7134df0d53ac25e3cc29afa7c05e24d721e7493..3e3049edaa4787f7bcb1020887b2770beb4a6cbe 100644 (file)
@@ -2,12 +2,44 @@
 
 class IPF_Auth_App extends IPF_Application
 {
-    public function getTitle()
+    public $userModel;
+
+    function configure($settings)
+    {
+        $this->userModel = \PFF\Arr::get($settings, 'auth_user_model', 'User');
+        \PFF\Container::set('auth', $this);
+    }
+
+    function getTitle()
+    {
+        return __('User Accounts');
+    }
+
+    function userQuery()
+    {
+        return \PFF\Container::databaseQuery()
+            ->from('auth_user')
+            ->orderBy('username')
+            ->asObject($this->userModel);
+    }
+
+    function findUser($id)
+    {
+        return $this->userQuery()->where('id', $id)->fetch();
+    }
+
+    function findUserByUsername($username)
+    {
+        return $this->userQuery()->where('username', $username)->fetch();
+    }
+
+    function createUser()
     {
-        return 'User Accounts';
+        $className = $this->userModel;
+        return new $className;
     }
 
-    static function login($request, $user)
+    function login($request, $user)
     {
         $request->user = $user;
         $request->session->data = array(
@@ -15,9 +47,9 @@ class IPF_Auth_App extends IPF_Application
         );
     }
 
-    static function logout($request)
+    function logout($request)
     {
-        $request->user = new User;
+        $request->user = new AnonymousUser;
         $request->session->data = array(
             'login_time' => gmdate('Y-m-d H:i:s')
         );
index 19a76fd3b712e5150ed5d52852009bcbdb1a7f46..696b8974a9173beb19f7cf5d7f30fd0af7d885e0 100644 (file)
@@ -13,9 +13,7 @@ class IPF_Auth_Command_CreateSuperUser
         $password = IPF_Shell::ask('  Password: ');
         $email    = IPF_Shell::ask('  E-mail: ');
 
-        $project = IPF_Project::getInstance();
-
-        $su = new User;
+        $su = \PFF\Container::auth()->createUser();
         $su->username     = $username;
         $su->email        = $email;
         $su->is_staff     = true;
index 0cf563a118fcb504ccce53fd0fb0e6fe4ec7bdd6..90c6d155eb375ec247eca759fc398695f6f4014d 100644 (file)
@@ -10,7 +10,7 @@ class IPF_Auth_Middleware
 
         $user_id = \PFF\Arr::get($request->session->data, self::SessionKey, 0);
         if ($user_id > 0) {
-            $request->user = User::find($user_id);
+            $request->user = \PFF\Container::auth()->findUser($user_id);
             if ($request->user && 43200 < IPF_Utils::dateCompare($request->user->last_login)) {
                 $request->user->last_login = gmdate('Y-m-d H:i:s');
                 $request->user->save();
@@ -18,7 +18,7 @@ class IPF_Auth_Middleware
         }
 
         if (!$request->user)
-            $request->user = new User;
+            $request->user = new AnonymousUser;
 
         return false;
     }
index 933cdcbe8ddcfd0a933edb123883b3edfec79c7b..a2e75c72f9d702513506c3e9f91291d6b04b8a26 100644 (file)
@@ -1,8 +1,58 @@
 <?php
 
-class User
+abstract class DBObject
 {
-    public $id, $username, $password, $email, $is_active, $is_staff, $is_superuser, $last_login;
+    public $id;
+    protected $table = 'specify table name here';
+
+    public function save()
+    {
+        $r = new ReflectionObject($this);
+
+        $values = array();
+        foreach ($r->getProperties(ReflectionProperty::IS_PUBLIC) as $p) {
+            $name = $p->getName();
+            if ($name === 'id' || $name[0] === '_')
+                continue;
+            $values[$name] = $p->getValue($this);
+        }
+
+        if ($this->id) {
+            \PFF\Container::databaseQuery()
+                ->update($this->table, $values, $this->id)
+                ->execute();
+        } else {
+            $this->id = \PFF\Container::databaseQuery()
+                ->insertInto($this->table, $values)
+                ->execute();
+        }
+    }
+}
+
+class AnonymousUser
+{
+    public $id = 0;
+
+    public function __toString()
+    {
+        return 'Anonymous';
+    }
+
+    function isAnonymous()
+    {
+        return true;
+    }
+
+    public function can(/* $permission ... */)
+    {
+        return false;
+    }
+}
+
+class User extends DBObject
+{
+    protected $table = 'auth_user';
+    public $username, $password, $email, $is_active, $is_staff, $is_superuser, $last_login;
 
     public function __toString()
     {
@@ -20,31 +70,14 @@ class User
             $this->password = '';
     }
 
-    function isAnonymous()
-    {
-        return 0 === (int)$this->id;
-    }
-
-    public static function find($id)
-    {
-        return self::query()->where('id', $id)->fetch();
-    }
-
-    public static function checkCreditentials($username, $password)
+    function checkPassword($raw_password)
     {
-        $user = self::query()->where('username', $username)->fetch();
-        if ($user && $user->is_active && IPF_Crypto::checkPassword($password, $user->password))
-            return $user;
-        else
-            return false;
+        return $this->is_active && IPF_Crypto::checkPassword($raw_password, $this->password);
     }
 
-    public static function query()
+    function isAnonymous()
     {
-        return \PFF\Container::databaseQuery()
-            ->from('auth_user')
-            ->orderBy('username')
-            ->asObject('User');
+        return false;
     }
 
     public function permissions()
@@ -103,9 +136,10 @@ class User
     }
 }
 
-class Role
+class Role extends DBObject
 {
-    public $id, $name;
+    protected $table = 'auth_role';
+    public $name;
 
     public function __toString()
     {
@@ -127,11 +161,37 @@ class Role
             ->where('role_id', $this->id)
             ->fetchAll();
     }
+
+    public function join($user)
+    {
+        \PFF\Container::databaseQuery()
+            ->insertInto('auth_user_role')
+            ->values(array('user_id' => $user->id, 'role_id' => $this->id))
+            ->execute();
+    }
+
+    public function leave($user)
+    {
+        if ($this->id)
+            self::leaveAll($user, $this->id);
+    }
+
+    public static function leaveAll($user, $only=null)
+    {
+        $cond = array('user_id' => $user->id);
+        if ($only)
+            $cond['role_id'] = $only;
+        \PFF\Container::databaseQuery()
+            ->deleteFrom('auth_user_role')
+            ->where($cond)
+            ->execute();
+    }
 }
 
-class Permission
+class Permission extends DBObject
 {
-    public $id, $name, $title;
+    protected $table = 'auth_permission';
+    public $name;
 
     public static function query()
     {
@@ -140,5 +200,49 @@ class Permission
             ->asObject('Permission')
             ->orderBy('name');
     }
+
+    public function grant($obj)
+    {
+        list($table, $data) = self::link($obj);
+        $data['permission_id'] = $this->id;
+        \PFF\Container::databaseQuery()->insertInto($table, $data)->execute();
+    }
+
+    public static function grantAll($permissions, $obj)
+    {
+        if (!$permissions)
+            return;
+
+        list($table, $data) = self::link($obj);
+        $values = array();
+        foreach ($permissions as $p)
+            $values[] = array_merge($data, array('permission_id' => $p->id));
+        \PFF\Container::databaseQuery()->insertInto($table, $values)->execute();
+    }
+
+    public function revoke($obj)
+    {
+        if ($this->id)
+            self::revokeAll($obj, $this->id);
+    }
+
+    public static function revokeAll($obj, $only=null)
+    {
+        list($table, $cond) = self::link($obj);
+        if ($only)
+            $cond['permission_id'] = $only;
+        \PFF\Container::databaseQuery()->deleteFrom($table)->where($cond)->execute();
+    }
+
+    private static function link($obj)
+    {
+        if ($obj instanceof User) {
+            return array('auth_user_permission', array('user_id' => $obj->id));
+        } elseif ($obj instanceof Role) {
+            return array('auth_role_permission', array('role_id' => $obj->id));
+        } else {
+            throw new IPF_Exception('Bad argument.');
+        }
+    }
 }
 
diff --git a/ipf/form/objectform.php b/ipf/form/objectform.php
new file mode 100644 (file)
index 0000000..7732d83
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+abstract class IPF_ObjectForm extends IPF_Form
+{
+    public function __construct($data=null, $object=null, $extra=array())
+    {
+        parent::__construct($data, $extra);
+
+        if ($object) {
+            foreach ($this->fields as $name => $field) {
+                if (array_key_exists($name, $this->initial))
+                    continue;
+
+                if (property_exists($object, $name)) {
+                    $this->initial[$name] = $object->$name;
+                } elseif (method_exists($object, $name)) {
+                    $this->initial[$name] = $object->$name();
+                }
+            }
+        }
+    }
+
+    public function toObject($object)
+    {
+        foreach ($this->fields as $name => $field) {
+            if (property_exists($object, $name)) {
+                $object->$name = $this->cleaned_data[$name];
+            } elseif (method_exists($object, 'set'.ucfirst($name))) {
+                $m = 'set'.ucfirst($name);
+                $object->$m($this->cleaned_data[$name]);
+            }
+        }
+    }
+}
+