source: trunk/server/www/app/app_controller.php @ 234

Last change on this file since 234 was 234, checked in by sander, 11 years ago

Merge the design branch to the trunk

File size: 5.6 KB
Line 
1<?php
2
3/**
4 * The global AppController.
5 *
6 * Takes care of authentication for all controllers
7 *
8 * The authentication model comes from Studio Canaria:
9 * http://www.studiocanaria.com/articles/cakephp_auth_component_users_groups_permissions_revisited
10 */
11class AppController extends Controller
12{
13        /**
14         * @var $components array Array of components to load for every controller in the application
15         */
16        public $components = array('AuthCert', 'Session', 'Cookie');
17
18        /**
19         * Application hook which runs prior to each controller action
20         */
21        public function beforeFilter()
22        {
23                //Override default fields used by Auth component
24                $this->AuthCert->fields = array('username'=>'email_address','password'=>'password');
25                //Set application wide actions which do not require authentication
26                $this->AuthCert->allow(array());
27                //Set the default redirect for users who logout
28                $this->AuthCert->logoutRedirect = '/';
29                //Set the default redirect for users who login
30                $this->AuthCert->loginRedirect = '/';
31                //The error displayed when a login error occurs
32                $this->AuthCert->loginError = __('Login failed. Wrong e-mail address or password.', true);
33                //Extend auth component to include authorisation via isAuthorized action
34                $this->AuthCert->authorize = 'controller';
35                //Restrict access to only users with an active account
36                $this->AuthCert->userScope = array('User.active = 1');
37                //Pass auth component data over to view files
38                $this->set('Auth',$this->AuthCert->user());
39        }
40
41        /**
42         * Application hook which runs after each action but, before the view file is
43         * rendered
44         */
45        public function beforeRender()
46        {
47                //If we have an authorised user logged then pass over an array of controllers
48                //to which they have index action permission
49                $topControllers = array();
50                $bottomControllers = array(
51                        __('Factories', true) => '/factories',
52                );
53
54                if ($this->AuthCert->user()) {
55                        $bottomControllers[__('Requests', true)] = '/requests';
56                        $bottomControllers[__('Your account', true)] = '/users/view';
57                }
58
59                $bottomControllers[__('Manuals', true)] = 'http://code.officeshots.org/trac/officeshots/wiki/Documentation';
60
61                if ($this->__permitted('users', 'admin_index')) {
62                        $bottomControllers[__('Users', true)] = '/admin/users';
63                        $bottomControllers[__('Groups', true)] = '/admin/groups';
64                }
65
66                if (!$this->AuthCert->hasCert) {
67                        if ($this->AuthCert->user()) {
68                                $topControllers[__('Logout', true)] = '/users/logout';
69                        } else {
70                                $topControllers[__('Login', true)] = '/users/login';
71                        }
72                }
73
74                // The currently set language
75                $language = $this->__getLanguage();
76
77
78                $this->set(compact('topControllers', 'bottomControllers', 'language'));
79        }
80
81        /**
82         * Called by Auth component for establishing whether the current authenticated
83         * user has authorization to access the current controller:action
84         *
85         * @return true if authorised/false if not authorized
86         */
87        public function isAuthorized()
88        {
89                return $this->__permitted($this->name, $this->action);
90        }
91
92        /**
93         * Helper function returns true if the currently authenticated user has permission
94         * to access the controller:action specified by $controllerName:$actionName
95         *
96         * @param $controllerName Object
97         * @param $actionName Object
98         * @return
99         */
100        public function __permitted($controllerName, $actionName)
101        {
102                if (!$user_id = $this->AuthCert->user('id')) {
103                        return false;
104                }
105
106                //Ensure checks are all made lower case
107                $controllerName = low($controllerName);
108                $actionName = low($actionName);
109               
110                //If permissions have not been cached to session...
111                if (!$this->Session->check('Permissions')) {
112                        //...then build permissions array and cache it
113                       
114                        // Set the global permissions for all users that are logged in
115                        $permissions = array(
116                                'users:logout',
117                                'users:index',
118                                'users:view',
119                                'users:edit',
120                                'requests:index',
121                                'requests:view',
122                                'requests:add',
123                                'requests:download',
124                                'results:view',
125                                'results:download',
126                        );
127
128                        //Import the User Model so we can build up the permission cache
129                        App::import('Model', 'User');
130                        $thisUser = new User();
131
132                        //Now bring in the current users full record along with groups
133                        $thisGroups = $thisUser->find(array('User.id' => $user_id));
134                        $thisGroups = $thisGroups['Group'];
135                        foreach ($thisGroups as $thisGroup) {
136                                $thisPermissions = $thisUser->Group->find(array('Group.id' => $thisGroup['id']));
137                                $thisPermissions = $thisPermissions['Permission'];
138                                foreach ($thisPermissions as $thisPermission) {
139                                        $permissions[] = $thisPermission['name'];
140                                }
141                        }
142
143                        //write the permissions array to session
144                        $this->Session->write('Permissions', $permissions);
145                } else {
146                        //...they have been cached already, so retrieve them
147                        $permissions = $this->Session->read('Permissions');
148                }
149
150                //Now iterate through permissions for a positive match
151                foreach ($permissions as $permission) {
152                        if ($permission == '*') {
153                                return true; //Super Admin Bypass Found
154                        }
155                        if ($permission == $controllerName.':*') {
156                                return true; //Controller Wide Bypass Found
157                        }
158                        if ($permission == $controllerName.':'.$actionName) {
159                                return true; //Specific permission found
160                        }
161                }
162                return false;
163        }
164
165        /**
166         * Set the language based on the session or a cookie
167         */
168        private function __setLanguage()
169        {
170                if ($this->Cookie->read('lang') && !$this->Session->check('Config.language')) {
171                        $this->Session->write('Config.language', $this->Cookie->read('lang'));
172                }
173        }
174
175        /**
176         * Get the language based on the session or a cookie
177         */
178        private function __getLanguage()
179        {
180                if ($language = $this->Cookie->read('lang')) {
181                        return $language;
182                }
183               
184                if ($language = $this->Session->read('Config.language')) {
185                        return $language;
186                }
187
188                return Configure::read('Config.language');
189        }
190}
191
192?>
Note: See TracBrowser for help on using the repository browser.