├── 001_Create_Smarty_Acl.php
├── LICENSE
├── README.md
├── SmartyAcl
├── config
│ └── smarty_acl.php
├── language
│ ├── english
│ │ └── smarty_acl_lang.php
│ └── portuguese-brazilian
│ │ └── smarty_acl_lang.php
├── libraries
│ └── Smarty_acl.php
├── models
│ └── Smarty_acl_model.php
└── views
│ └── auth
│ └── email
│ ├── admin
│ ├── activate.php
│ └── forgot_password.php
│ └── user
│ ├── activate.php
│ └── forgot_password.php
└── database.sql
/001_Create_Smarty_Acl.php:
--------------------------------------------------------------------------------
1 | config->load('smarty_acl', TRUE);
16 | //Get tables array
17 | $tables = $this->config->item('tables', 'smarty_acl');
18 | //Tables prefix
19 | $this->settings['prefix'] = $tables['prefix'] ? $tables['prefix'].'_' : '';
20 | // Table names
21 | $this->settings['users'] = $tables['users'];
22 | $this->settings['admins'] = $tables['admins'];
23 | $this->settings['roles'] = $this->settings['prefix'].$tables['roles'];
24 | $this->settings['modules'] = $this->settings['prefix'].$tables['modules'];
25 | $this->settings['module_permissions'] = $this->settings['prefix'].$tables['module_permissions'];
26 | $this->settings['password_resets'] = $this->settings['prefix'].$tables['password_resets'];
27 | $this->settings['login_attempts'] = $this->settings['prefix'].$tables['login_attempts'];
28 | }
29 |
30 | public function up()
31 | {
32 | //Load settings
33 | $this->get_settings();
34 | /**************** Start Create Tables ****************/
35 | //Create users
36 | $this->dbforge->add_field(array(
37 | 'id' => array(
38 | 'type' => 'INT',
39 | 'constraint' => 11,
40 | 'unsigned' => TRUE,
41 | 'auto_increment' => TRUE
42 | ),
43 | 'username' => array(
44 | 'type' => 'VARCHAR',
45 | 'constraint' => '191',
46 | 'unsigned' => TRUE,
47 | ),
48 | 'email' => array(
49 | 'type' => 'VARCHAR',
50 | 'constraint' => '191',
51 | 'unsigned' => TRUE,
52 | 'null' => TRUE,
53 | ),
54 | 'password' => array(
55 | 'type' => 'VARCHAR',
56 | 'constraint' => '191',
57 | ),
58 | 'name' => array(
59 | 'type' => 'VARCHAR',
60 | 'constraint' => '191',
61 | 'null' => TRUE,
62 | ),
63 | 'status' => array(
64 | 'type' => 'ENUM',
65 | 'constraint' => ['inactive', 'active', 'banned'],
66 | 'default' => 'active',
67 | ),
68 | 'ip' => array(
69 | 'type' => 'VARCHAR',
70 | 'constraint' => '191',
71 | ),
72 | 'last_login' => array(
73 | 'type' => 'timestamp',
74 | 'null' => true,
75 | ),
76 | 'email_verified_at' => array(
77 | 'type' => 'timestamp',
78 | 'null' => true,
79 | ),
80 | 'email_activator' => array(
81 | 'type' => 'VARCHAR',
82 | 'constraint' => '255',
83 | 'unsigned' => TRUE,
84 | 'null' => TRUE,
85 | ),
86 | 'email_activator_code' => array(
87 | 'type' => 'VARCHAR',
88 | 'constraint' => '255',
89 | 'null' => TRUE,
90 | ),
91 | 'remember_token' => array(
92 | 'type' => 'VARCHAR',
93 | 'constraint' => '255',
94 | 'unsigned' => TRUE,
95 | 'null' => TRUE,
96 | ),
97 | 'remember_token_code' => array(
98 | 'type' => 'VARCHAR',
99 | 'constraint' => '255',
100 | 'null' => TRUE,
101 | ),
102 | 'created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP',
103 | 'updated_at timestamp NOT NULL',
104 | ));
105 | $this->dbforge->add_key('id', TRUE);
106 | $this->dbforge->create_table($this->settings['users']);
107 | //Create admins
108 | $this->dbforge->add_field(array(
109 | 'id' => array(
110 | 'type' => 'INT',
111 | 'constraint' => 11,
112 | 'unsigned' => TRUE,
113 | 'auto_increment' => TRUE
114 | ),
115 | 'username' => array(
116 | 'type' => 'VARCHAR',
117 | 'constraint' => '191',
118 | 'unsigned' => TRUE,
119 | ),
120 | 'email' => array(
121 | 'type' => 'VARCHAR',
122 | 'constraint' => '191',
123 | 'unsigned' => TRUE,
124 | 'null' => TRUE,
125 | ),
126 | 'role_id' => array(
127 | 'type' => 'int',
128 | 'constraint' => '1',
129 | ),
130 | 'password' => array(
131 | 'type' => 'VARCHAR',
132 | 'constraint' => '191',
133 | ),
134 | 'name' => array(
135 | 'type' => 'VARCHAR',
136 | 'constraint' => '191',
137 | 'null' => TRUE,
138 | ),
139 | 'status' => array(
140 | 'type' => 'ENUM',
141 | 'constraint' => ['inactive', 'active', 'banned'],
142 | 'default' => 'active',
143 | ),
144 | 'ip' => array(
145 | 'type' => 'VARCHAR',
146 | 'constraint' => '191',
147 | ),
148 | 'last_login' => array(
149 | 'type' => 'timestamp',
150 | 'null' => true,
151 | ),
152 | 'email_verified_at' => array(
153 | 'type' => 'timestamp',
154 | 'null' => true,
155 | ),
156 | 'email_activator' => array(
157 | 'type' => 'VARCHAR',
158 | 'constraint' => '255',
159 | 'unsigned' => TRUE,
160 | 'null' => TRUE,
161 | ),
162 | 'email_activator_code' => array(
163 | 'type' => 'VARCHAR',
164 | 'constraint' => '255',
165 | 'null' => TRUE,
166 | ),
167 | 'remember_token' => array(
168 | 'type' => 'VARCHAR',
169 | 'constraint' => '255',
170 | 'unsigned' => TRUE,
171 | 'null' => TRUE,
172 | ),
173 | 'remember_token_code' => array(
174 | 'type' => 'VARCHAR',
175 | 'constraint' => '255',
176 | 'null' => TRUE,
177 | ),
178 | 'created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP',
179 | 'updated_at timestamp NOT NULL',
180 | ));
181 | $this->dbforge->add_key('id', TRUE);
182 | $this->dbforge->create_table($this->settings['admins']);
183 | //Create roles
184 | $this->dbforge->add_field(array(
185 | 'id' => array(
186 | 'type' => 'INT',
187 | 'constraint' => 11,
188 | 'unsigned' => TRUE,
189 | 'auto_increment' => TRUE
190 | ),
191 | 'name' => array(
192 | 'type' => 'VARCHAR',
193 | 'constraint' => '191',
194 | ),
195 | 'status' => array(
196 | 'type' => 'ENUM',
197 | 'constraint' => ['inactive', 'active'],
198 | 'default' => 'active',
199 | ),
200 | ));
201 | $this->dbforge->add_key('id', TRUE);
202 | $this->dbforge->create_table($this->settings['roles']);
203 | //Create modules
204 | $this->dbforge->add_field(array(
205 | 'id' => array(
206 | 'type' => 'INT',
207 | 'constraint' => 11,
208 | 'unsigned' => TRUE,
209 | 'auto_increment' => TRUE
210 | ),
211 | 'name' => array(
212 | 'type' => 'VARCHAR',
213 | 'constraint' => '191',
214 | ),
215 | 'controller' => array(
216 | 'type' => 'VARCHAR',
217 | 'constraint' => '191',
218 | ),
219 | 'permissions' => array(
220 | 'type' => 'JSON',
221 | ),
222 | ));
223 | $this->dbforge->add_key('id', TRUE);
224 | $this->dbforge->create_table($this->settings['modules']);
225 | //Create module permissions
226 | $this->dbforge->add_field(array(
227 | 'id' => array(
228 | 'type' => 'INT',
229 | 'constraint' => 11,
230 | 'unsigned' => TRUE,
231 | 'auto_increment' => TRUE
232 | ),
233 | 'role_id' => array(
234 | 'type' => 'INT',
235 | 'constraint' => '11',
236 | 'unsigned' => TRUE,
237 | ),
238 | 'module_id' => array(
239 | 'type' => 'INT',
240 | 'constraint' => '11',
241 | 'unsigned' => TRUE,
242 | ),
243 | 'permission' => array(
244 | 'type' => 'VARCHAR',
245 | 'constraint' => '191',
246 | ),
247 | ));
248 | $this->dbforge->add_key('id', TRUE);
249 | $this->dbforge->create_table($this->settings['module_permissions']);
250 | //Create password resets
251 | $this->dbforge->add_field(array(
252 | 'id' => array(
253 | 'type' => 'INT',
254 | 'constraint' => 11,
255 | 'unsigned' => TRUE,
256 | 'auto_increment' => TRUE
257 | ),
258 | 'type' => array(
259 | 'type' => 'ENUM',
260 | 'constraint' => ['admin', 'user'],
261 | 'default' => 'admin',
262 | ),
263 | 'email' => array(
264 | 'type' => 'VARCHAR',
265 | 'constraint' => '191',
266 | ),
267 | 'token' => array(
268 | 'type' => 'VARCHAR',
269 | 'constraint' => '191',
270 | ),
271 | 'token_code' => array(
272 | 'type' => 'VARCHAR',
273 | 'constraint' => '191',
274 | ),
275 | 'created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP',
276 | ));
277 | $this->dbforge->add_key('id', TRUE);
278 | $this->dbforge->create_table($this->settings['password_resets']);
279 | //Create login attempts
280 | $this->dbforge->add_field(array(
281 | 'id' => array(
282 | 'type' => 'INT',
283 | 'constraint' => 11,
284 | 'unsigned' => TRUE,
285 | 'auto_increment' => TRUE
286 | ),
287 | 'type' => array(
288 | 'type' => 'ENUM',
289 | 'constraint' => ['admin', 'user'],
290 | 'default' => 'admin',
291 | ),
292 | 'login' => array(
293 | 'type' => 'VARCHAR',
294 | 'constraint' => '191',
295 | ),
296 | 'ip' => array(
297 | 'type' => 'VARCHAR',
298 | 'constraint' => '191',
299 | ),
300 | 'created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP',
301 | ));
302 | $this->dbforge->add_key('id', TRUE);
303 | $this->dbforge->create_table($this->settings['login_attempts']);
304 | /**************** End Create Tables ****************/
305 | /**************** Start Set Foreign Keys ****************/
306 | //Foreign keys
307 | $this->db->query('ALTER TABLE '.$this->settings['module_permissions'].' ADD FOREIGN KEY (role_id) REFERENCES '.$this->settings['roles'].'(id) ON DELETE CASCADE ON UPDATE RESTRICT');
308 | $this->db->query('ALTER TABLE '.$this->settings['module_permissions'].' ADD FOREIGN KEY (module_id) REFERENCES '.$this->settings['modules'].'(id) ON DELETE CASCADE ON UPDATE RESTRICT');
309 | //Unique keys
310 | $this->db->query('ALTER TABLE '.$this->settings['admins'].' ADD UNIQUE (username, email, email_activator, remember_token)');
311 | $this->db->query('ALTER TABLE '.$this->settings['users'].' ADD UNIQUE (username, email, email_activator, remember_token)');
312 | /**************** End Set Foreign Keys ****************/
313 | /**************** Start Insert Data ****************/
314 | //Default roles
315 | $this->db->insert($this->settings['roles'],['name' => 'Super Admin']);
316 | $this->db->insert($this->settings['roles'],['name' => 'Admin']);
317 | $this->db->insert($this->settings['roles'],['name' => 'Demo']);
318 | //Default admin
319 | $this->db->insert($this->settings['admins'],[
320 | 'username' => 'admin',
321 | 'password' => '$2y$10$TmJKG3yV8o7kCycAdQI0/.7jJ5uhO3RC9pyJOMlbFHmbEzUk8JMfu',
322 | 'name' => 'Administrator',
323 | 'email' => 'admin@admin.com',
324 | 'role_id' => 1,
325 | 'status' => 'active',
326 | 'ip' => '172.19.0.1',
327 | 'email_verified_at' => date('Y-m-d H:i:s'),
328 | 'created_at' => date('Y-m-d H:i:s'),
329 | 'updated_at' => date('Y-m-d H:i:s')
330 | ]);
331 | /**************** End Insert Data ****************/
332 | }
333 |
334 | public function down()
335 | {
336 | //Load settings
337 | $this->get_settings();
338 | //Drop tables
339 | $this->dbforge->drop_table($this->settings['users']);
340 | $this->dbforge->drop_table($this->settings['admins']);
341 | $this->dbforge->drop_table($this->settings['roles']);
342 | $this->dbforge->drop_table($this->settings['modules']);
343 | $this->dbforge->drop_table($this->settings['module_permissions']);
344 | $this->dbforge->drop_table($this->settings['password_resets']);
345 | $this->dbforge->drop_table($this->settings['login_attempts']);
346 | }
347 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 rubensrocha
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Smarty ACL
3 | SmartyACL is a library with basic authentication and authorization functions for Codeigniter 3. This library was based on Ion Auth but with the addition of ACL / RBAC and some other features.
4 |
5 | ### Features
6 | - Register
7 | - Register admin or user
8 | - Send mail verification (optional)
9 | - Login
10 | - Single or Multi login(email, username or both)
11 | - Limit max attempts
12 | - Remember me
13 | - Checks account status(inactive or banned) (optional)
14 | - Check mail verification (optional)
15 | - Forgot Password
16 | - Send reset password mail
17 | - Reset Password
18 | - Validate security code and update user email/password
19 | - Roles
20 | - Create, update, delete
21 | - Assign module permissions
22 | - Modules
23 | - Create, update and delete
24 | - Admin Group - Users with role/permission access
25 | - User Group - Common users without role/permission access
26 | - Cache data to improve performance (optional)
27 |
28 | ### Summary
29 | - [Requirements](#requirements)
30 | - [Demo](#demo)
31 | - [Installation](#installation)
32 | - [Default Login](#default-login)
33 | - [Usage](#usage)
34 | - [Contributing](#contributing)
35 | - [Support](#support)
36 | - [References](#references)
37 |
38 | ### Requirements
39 | - Codeigniter 3 (developed on 3.1.11)
40 | - PHP 7.x (developed on 7.3)
41 |
42 | ### Demo
43 | Download a demo application [here](https://github.com/rubensrocha/codeigniter-smarty-acl-demo)
44 |
45 | ### Installation
46 | 1. Download latest released version
47 | 2. Put SmartyAcl folder on `application/third_party` directory
48 | 3. Add to `$autoload['packages']`¹ in `application/config/autoload.php`
49 | ```
50 | $autoload['packages'] = array(APPPATH.'third_party/SmartyAcl');
51 | ```
52 | 4. Import DB tables using migration or database.sql file
53 | 5. Config library preferences on `application/third_party/SmartyAcl/config/smarty_acl.php`
54 |
55 | ¹ Alternatively, you can copy the contents of the SmartyAcl folder to the respective directories in the application folder and load the library directly into the controller using `$this->load->library('smarty_acl');`
56 |
57 | ### Default Login
58 | Username: admin
59 | Password: 123456
60 | ### Usage
61 | Methods List
62 |
63 | | Method | Description |
64 | | :----- | :------- |
65 | | [register()](#register-admin) | Register a new Admin User |
66 | | [register_user()](#register-user) | Register a new User |
67 | | [login()](#login) | User or Admin Login |
68 | | [activate()](#activate-admin-or-user) | Activate admin user with code(email) |
69 | | [activate_user()](#activate-admin-or-user) | Activate user with code(email) |
70 | | [resend_activation()](#resend-activation-mail) | Resend email confirmation code (admin/user) |
71 | | [forgotten_password()](#forgotten-password) | Send reset password email (admin/user) |
72 | | [forgotten_password_check()](#forgotten-password-check) | Validate forgotten password code (admin/user) |
73 | | [reset_password()](#reset-password) | Reset email and password (admin/user) |
74 | | [logged_in()](#logged-in) | Check if user is logged in (admin/user) |
75 | | [logout()](#logout) | Logout current logged in user (admin/user) |
76 | | [roles()](#get-roles) | Get roles list |
77 | | [role()](#get-role) | Get single role |
78 | | [create_role()](#create-role) | Create a new Role |
79 | | [update_role()](#update-role) | Update a single Role |
80 | | [delete_role()](#delete-role) | Delete a single Role |
81 | | [modules()](#get-modules) | Get modules list |
82 | | [module()](#get-module) | Get single module |
83 | | [create_module()](#create-module) | Create a new Module |
84 | | [update_module()](#update-module) | Update a single Module |
85 | | [delete_module()](#delete-module) | Delete a single Module |
86 | | [module_permissions()](#get-module-permissions) | Get a single Module Permissions |
87 | | [authorized()](#authorized) | Check if logged in user is authorized to access current module |
88 | | [module_authorized()](#module-authorized) | Check if logged in user has permission to a specific module |
89 | | [authorized_action()](#authorized-module-action) | Check if logged in user has permission to current module action method |
90 | | [has_permission()](#has-permission) | Check if logged in user has permission to a specific module action method |
91 | | [admins()](#get-admins) | Get admins |
92 | | [users()](#get-users) | Get users |
93 | | [get_user()](#get-user) | Get a single user |
94 | | [get_admin()](#get-admin) | Get a single admin |
95 | | [update_user()](#update-user) | Update a single user (admin/user) |
96 | | [delete_user()](#delete-user) | Delete a single user (admin/user) |
97 | | [set_delimiter()](#errors-delimiters) | Set delimiters for error messages |
98 | | [errors()](#error-messages) | Show error messages |
99 |
100 | #### Register Admin
101 | Call:
102 | ```php
103 | $this->smarty_acl->register($identity, $password, $email, $additional_data, $role_id);
104 | ```
105 | Responses:
106 | ```
107 | int = user registered
108 | array = user data array if verification is enabled but 'email_sender' is disabled
109 | false(bool) = failed to register
110 | ```
111 |
112 | | Field | Required | Info |
113 | | :-----: | :--------: | :-------: |
114 | | $identity | yes | field used to register/login user (username, email, phone, etc) |
115 | | $password | yes | user password |
116 | | $email | yes | user email address |
117 | | $additional_data | no | array with additional data(name, address, country, etc) (optional) |
118 | | $role_id | no | role id to assign(optional). If null, will use `$config['default_role']` |
119 |
120 | #### Register User
121 | Call:
122 | ```php
123 | $this->smarty_acl->register_user($identity, $password, $email, $additional_data, $role_id);
124 | ```
125 | Responses:
126 | ```
127 | int = user registered
128 | array = user data array if verification is enabled but 'email_sender' is disabled
129 | false(bool) = failed to register
130 | ```
131 |
132 | | Field | Required | Info |
133 | | :-----: | :--------: | :-------: |
134 | | $identity | yes | field used to register/login user (username, email, phone, etc) |
135 | | $password | yes | user password |
136 | | $email | yes | user email address |
137 | | $additional_data | no | array with additional data(name, address, country, etc) (optional) |
138 |
139 | #### Login
140 | Call:
141 | ```php
142 | $this->smarty_acl->login($identity, $password, $remember, $admin);
143 | ```
144 | Response:
145 | ```
146 | (bool) = true if logged in
147 | ```
148 |
149 | | Field | Required | Info |
150 | | :-----: | :--------: | :-------: |
151 | | $identity | yes | field used to register/login user (username, email, phone, etc) |
152 | | $password | yes | user password |
153 | | $admin | no (default TRUE) | (bool) set FALSE to user login |
154 |
155 | #### Activate Admin or user
156 | Call:
157 | ```php
158 | //Admin user
159 | $this->smarty_acl->activate($user_id, $code);
160 | //User
161 | $this->smarty_acl->activate_user($user_id, $code);
162 | ```
163 | Response:
164 | ```
165 | (bool) = true if activated
166 | ```
167 |
168 | | Field | Required | Info |
169 | | :-----: | :--------: | :-------: |
170 | | $user_id | yes | User ID |
171 | | $code | yes | Activation Security Code |
172 |
173 | #### Resend Activation Mail
174 | Call:
175 | ```php
176 | $this->smarty_acl->resend_activation($email, $admin);
177 | ```
178 | Response:
179 | ```
180 | (bool) = true if sent successfully
181 | ```
182 |
183 | | Field | Required | Info |
184 | | :-----: | :--------: | :-------: |
185 | | $email | yes | User email address |
186 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
187 |
188 | #### Forgotten Password
189 | Call:
190 | ```php
191 | $this->smarty_acl->forgotten_password($email, $admin);
192 | ```
193 | Response:
194 | ```
195 | (bool) = true if sent successfully
196 | ```
197 |
198 | | Field | Required | Info |
199 | | :-----: | :--------: | :-------: |
200 | | $email | yes | User email address |
201 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
202 |
203 | #### Forgotten Password Check
204 | Call:
205 | ```php
206 | $this->smarty_acl->forgotten_password_check($code, $admin);
207 | ```
208 | Response:
209 | ```
210 | (bool) = false if code is invalid or expired
211 | (array) = user data array
212 | ```
213 |
214 | | Field | Required | Info |
215 | | :-----: | :--------: | :-------: |
216 | | $code | yes | Secret Code |
217 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
218 |
219 | #### Reset Password
220 | Call:
221 | ```php
222 | $this->smarty_acl->reset_password($user, $email, $password, $admin);
223 | ```
224 | Response:
225 | ```
226 | (bool) = true if updated successfully
227 | ```
228 |
229 | | Field | Required | Info |
230 | | :-----: | :--------: | :-------: |
231 | | $user | yes | Array with current user data(from forgotten_password_check()) |
232 | | $email | yes | New email address |
233 | | $password | yes | New password |
234 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
235 |
236 | #### Logged in
237 | Call:
238 | ```php
239 | $this->smarty_acl->logged_in($admin);
240 | ```
241 | Response:
242 | ```
243 | (bool) = true if user is logged in
244 | ```
245 |
246 | | Field | Required | Info |
247 | | :-----: | :--------: | :-------: |
248 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
249 |
250 | #### Logout
251 | Call:
252 | ```php
253 | $this->smarty_acl->logout($admin);
254 | ```
255 | Response:
256 | ```
257 | (bool) = true if user is logged out
258 | ```
259 |
260 | | Field | Required | Info |
261 | | :-----: | :--------: | :-------: |
262 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
263 |
264 | #### Get Roles
265 | Call:
266 | ```php
267 | $this->smarty_acl->roles($result);
268 | ```
269 | Response:
270 | ```
271 | Roles list as object or array
272 | ```
273 |
274 | | Field | Required | Info |
275 | | :-----: | :--------: | :-------: |
276 | | $result | no (default TRUE) | (bool) set FALSE to return array |
277 |
278 | #### Create Role
279 | Call:
280 | ```php
281 | $this->smarty_acl->create_role($data);
282 | ```
283 | Response:
284 | ```
285 | (bool) = true if created
286 | ```
287 |
288 | | Field | Required | Info |
289 | | :-----: | :--------: | :-------: |
290 | | $data | yes | array with role fields/values |
291 |
292 | #### Get Role
293 | Call:
294 | ```php
295 | $this->smarty_acl->role($role_id);
296 | ```
297 | Response:
298 | ```
299 | (object) = if found
300 | (bool) = false if not found
301 | ```
302 |
303 | | Field | Required | Info |
304 | | :-----: | :--------: | :-------: |
305 | | $role_id | yes | Role ID |
306 |
307 | #### Update Role
308 | Call:
309 | ```php
310 | $this->smarty_acl->update_role($role_id, $data);
311 | ```
312 | Response:
313 | ```
314 | (bool) = true if updated
315 | ```
316 |
317 | | Field | Required | Info |
318 | | :-----: | :--------: | :-------: |
319 | | $role_id | yes | Role ID |
320 | | $data | yes | array with role fields/values |
321 |
322 | #### Delete Role
323 | Call:
324 | ```php
325 | $this->smarty_acl->delete_role($role_id);
326 | ```
327 | Response:
328 | ```
329 | (bool) = true if deleted
330 | ```
331 |
332 | | Field | Required | Info |
333 | | :-----: | :--------: | :-------: |
334 | | $role_id | yes | Role ID |
335 |
336 | #### Get Modules
337 | Call:
338 | ```php
339 | $this->smarty_acl->modules($result);
340 | ```
341 | Response:
342 | ```
343 | Roles list as object or array
344 | ```
345 |
346 | | Field | Required | Info |
347 | | :-----: | :--------: | :-------: |
348 | | $result | no (default TRUE) | (bool) set FALSE to return array |
349 |
350 | #### Create Module
351 | Call:
352 | ```php
353 | $this->smarty_acl->create_module($data);
354 | ```
355 | Response:
356 | ```
357 | (bool) = true if created
358 | ```
359 |
360 | | Field | Required | Info |
361 | | :-----: | :--------: | :-------: |
362 | | $data | yes | array with module fields/values |
363 |
364 | #### Get Module
365 | Call:
366 | ```php
367 | $this->smarty_acl->module($module_id);
368 | ```
369 | Response:
370 | ```
371 | (object) = if found
372 | (bool) = false if not found
373 | ```
374 |
375 | | Field | Required | Info |
376 | | :-----: | :--------: | :-------: |
377 | | $role_id | yes | Role ID |
378 |
379 | #### Update Module
380 | Call:
381 | ```php
382 | $this->smarty_acl->update_module($module_id, $data);
383 | ```
384 | Response:
385 | ```
386 | (bool) = true if updated
387 | ```
388 |
389 | | Field | Required | Info |
390 | | :-----: | :--------: | :-------: |
391 | | $role_id | yes | Role ID |
392 | | $data | yes | array with module fields/values |
393 |
394 | #### Delete Module
395 | Call:
396 | ```php
397 | $this->smarty_acl->delete_module($module_id);
398 | ```
399 | Response:
400 | ```
401 | (bool) = true if deleted
402 | ```
403 |
404 | | Field | Required | Info |
405 | | :-----: | :--------: | :-------: |
406 | | $role_id | yes | Role ID |
407 |
408 | #### Get Module Permissions
409 | Call:
410 | ```php
411 | $this->smarty_acl->module_permissions($role_id);
412 | ```
413 | Response:
414 | ```
415 | (array) = multidimensional array with
416 | {
417 | [module_id] => {
418 | [permission_id] => [permission_method_name]
419 | }
420 | }
421 | ```
422 |
423 | | Field | Required | Info |
424 | | :-----: | :--------: | :-------: |
425 | | $role_id | yes | Role ID |
426 |
427 | #### Authorized
428 | Call:
429 | ```php
430 | $this->smarty_acl->authorized();
431 | ```
432 | Response:
433 | ```
434 | redirect to unathorized route if not authorized
435 | ```
436 |
437 | #### Module Authorized
438 | Call:
439 | ```php
440 | $this->smarty_acl->module_authorized($module);
441 | ```
442 | Response:
443 | ```
444 | (bool) = false if not authorized
445 | ```
446 |
447 | | Field | Required | Info |
448 | | :-----: | :--------: | :-------: |
449 | | $module | yes | Module Controller Name |
450 |
451 | #### Authorized Module Action
452 | Call:
453 | ```php
454 | $this->smarty_acl->authorized_action();
455 | ```
456 | Response:
457 | ```
458 | redirect to unathorized route if not authorized
459 | ```
460 |
461 | #### Has Permission
462 | Call:
463 | ```php
464 | $this->smarty_acl->has_permission($permission);
465 | ```
466 | Response:
467 | ```
468 | (bool) = false if not authorized
469 | ```
470 |
471 | | Field | Required | Info |
472 | | :-----: | :--------: | :-------: |
473 | | $permission | yes | Module Permission Name |
474 |
475 | #### Get Admins
476 | Call:
477 | ```php
478 | $this->smarty_acl->admins($result);
479 | ```
480 | Response:
481 | ```
482 | Admins list as object or array
483 | ```
484 |
485 | | Field | Required | Info |
486 | | :-----: | :--------: | :-------: |
487 | | $result | no (default TRUE) | (bool) set FALSE to return array |
488 |
489 | #### Get Users
490 | Call:
491 | ```php
492 | $this->smarty_acl->users($result);
493 | ```
494 | Response:
495 | ```
496 | Users list as object or array
497 | ```
498 |
499 | | Field | Required | Info |
500 | | :-----: | :--------: | :-------: |
501 | | $result | no (default TRUE) | (bool) set FALSE to return array |
502 |
503 | #### Get User
504 | Call:
505 | ```php
506 | $this->smarty_acl->get_user($user_id);
507 | ```
508 | Response:
509 | ```
510 | User data as array
511 | ```
512 |
513 | | Field | Required | Info |
514 | | :-----: | :--------: | :-------: |
515 | | $user_id | yes | User ID |
516 |
517 | #### Get Admin
518 | Call:
519 | ```php
520 | $this->smarty_acl->get_admin($user_id);
521 | ```
522 | Response:
523 | ```
524 | Admin data as array
525 | ```
526 |
527 | | Field | Required | Info |
528 | | :-----: | :--------: | :-------: |
529 | | $user_id | yes | User ID |
530 |
531 | #### Update User
532 | Call:
533 | ```php
534 | $this->smarty_acl->update_user($data, $user_id, $admin);
535 | ```
536 | Response:
537 | ```
538 | (bool) = true if updated
539 | ```
540 |
541 | | Field | Required | Info |
542 | | :-----: | :--------: | :-------: |
543 | | $data | yes | array with user fields/values |
544 | | $user_id | yes | User ID |
545 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
546 |
547 | #### Delete User
548 | Call:
549 | ```php
550 | $this->smarty_acl->delete_user($user_id,$admin);
551 | ```
552 | Response:
553 | ```
554 | (bool) = true if deleted
555 | ```
556 |
557 | | Field | Required | Info |
558 | | :-----: | :--------: | :-------: |
559 | | $user_id | yes | User ID |
560 | | $admin | no (default TRUE) | (bool) set FALSE to use for users |
561 |
562 | #### Errors Delimiters
563 | Call:
564 | ```php
565 | $this->smarty_acl->set_delimiter($start, $end);
566 | ```
567 | Response:
568 | ```
569 | (bool) = true if set successfully
570 | ```
571 |
572 | | Field | Required | Info |
573 | | :-----: | :--------: | :-------: |
574 | | $start | yes | Start delimiter (`
,
,`, etc) |
575 | | $end | yes | End delimiter (`,,`, etc) |
576 |
577 | #### Error Messages
578 | Call:
579 | ```php
580 | $this->smarty_acl->errors();
581 | ```
582 | Response:
583 | ```
584 | (string) = for single error
585 | (array) = for multiple errors
586 | ```
587 |
588 | ### Contributing
589 | Feel free to contribute with corrections, optimizations or improvements. Just send a [Pull Request](https://github.com/rubensrocha/codeigniter-smarty-acl/pulls) with your contribution.
590 | ### Support
591 | If you found a bug, [Create an Issue](https://github.com/rubensrocha/codeigniter-smarty-acl/issues).
592 | If you're having an issue with CodeIgniter or for general help with development I recommend checking out the [CodeIgniter Forums](http://forum.codeigniter.com/)
593 | ### References
594 | - [Ion Auth](https://github.com/benedmunds/CodeIgniter-Ion-Auth) repository used as reference
595 |
--------------------------------------------------------------------------------
/SmartyAcl/config/smarty_acl.php:
--------------------------------------------------------------------------------
1 | 'smtp.mailtrap.io', // your smtp host url
72 | 'smtp_port' => '2525', // your smtp host port(outgoing). Eg.: 465, 587
73 | 'smtp_user' => '', // your smtp username
74 | 'smtp_pass' => '', // your smtp password
75 | 'smtp_crypto' => 'NULL', // SSL, TLS, NULL
76 | 'protocol' => 'smtp', // mail protocol. smtp, sendmail, mail
77 | 'charset' => 'utf-8', // charset
78 | 'mailtype' => 'html', // text or html
79 | 'crlf' => "\r\n", //Newline character. (Use “\r\n” to comply with RFC 822).
80 | 'newline' => "\r\n", //Newline character. (Use “\r\n” to comply with RFC 822).
81 | ];
82 | /*
83 | | -------------------------------------------------------------------------
84 | | Email templates
85 | | -------------------------------------------------------------------------
86 | | Folder where email templates are stored.
87 | | Default: auth/email/
88 | */
89 | $config['email_templates'] = 'auth/email/';
90 | /*
91 | | -------------------------------------------------------------------------
92 | | Identity
93 | | -------------------------------------------------------------------------
94 | | The values in this column, alongside password, will be used for login purposes
95 | | Default: username
96 | */
97 | $config['identity'] = 'username';
98 | /*
99 | | -------------------------------------------------------------------------
100 | | Multi Identity
101 | | @param bool FALSE(identity only)
102 | | @param string column_name(identity or column_name)
103 | | -------------------------------------------------------------------------
104 | | Allows login using only the identity or email as optional.
105 | | Eg: Login with username or email on same field
106 | | Default: FALSE
107 | */
108 | $config['multi_identity'] = FALSE;
109 | /*
110 | | -------------------------------------------------------------------------
111 | | Default Role
112 | | -------------------------------------------------------------------------
113 | | Default role id assigned to register new admin user
114 | | Default: 2 (admin group)
115 | */
116 | $config['default_role'] = 2;
117 | /*
118 | | -------------------------------------------------------------------------
119 | | Default Unauthorized Route
120 | | -------------------------------------------------------------------------
121 | | Default route name for unauthorized access
122 | | Default:
123 | */
124 | $config['unauthorized_route'] = 'unauthorized';
125 | /*
126 | | -------------------------------------------------------------------------
127 | | Error and Messages Delimiters
128 | | -------------------------------------------------------------------------
129 | | ''(empty) or html element. , , , etc
130 | */
131 | $config['message_start_delimiter'] = ''; // Message start delimiter
132 | $config['message_end_delimiter'] = ''; // Message end delimiter
133 | /*
134 | | -------------------------------------------------------------------------
135 | | Password algorithm
136 | | -------------------------------------------------------------------------
137 | | Default algorithm to hash password
138 | | Default: PASSWORD_BCRYPT
139 | */
140 | $config['password_algo'] = PASSWORD_BCRYPT;
141 | /*
142 | | -------------------------------------------------------------------------
143 | | Forgot Password Expiration
144 | | -------------------------------------------------------------------------
145 | | The number of seconds after which a forgot password request will expire. If set to 0, forgot password requests will not expire.
146 | | Default: 1800 (30 min)
147 | */
148 | $config['forgot_password_expiration'] = 1800;
149 | /*
150 | | -------------------------------------------------------------------------
151 | | Min Password Length
152 | | -------------------------------------------------------------------------
153 | | Minimum Required Length of Password (not enforced by lib, use this with form validation)
154 | | Default: 6
155 | */
156 | $config['min_password_length'] = 6;
157 | /*
158 | | -------------------------------------------------------------------------
159 | | Max Login Attempts
160 | | -------------------------------------------------------------------------
161 | | The maximum number of failed login attempts.
162 | | Default: 3
163 | */
164 | $config['maximum_login_attempts'] = 3;
165 | /*
166 | | -------------------------------------------------------------------------
167 | | Login Lockout Time
168 | | -------------------------------------------------------------------------
169 | | The number of seconds to lockout an account due to exceeded attempts. You should not use a value below 60 (1 minute)
170 | | Default: 600 (10 min)
171 | */
172 | $config['lockout_time'] = 600;
173 | /*
174 | | -------------------------------------------------------------------------
175 | | Session Expiration Time
176 | | -------------------------------------------------------------------------
177 | | How long to remember the user (seconds). Set to zero for no expiration - see sess_expiration in CodeIgniter Session config for session expiration
178 | | Default: 86400 (24 hours)
179 | */
180 | $config['session_expire'] = 86400;
181 | /*
182 | | -------------------------------------------------------------------------
183 | | Session Recheck Time
184 | | -------------------------------------------------------------------------
185 | | The number of seconds after which the session is checked again against database to see if the user still exists and is active. Leave 0 if you don't want session recheck
186 | | Default: 0
187 | */
188 | $config['session_recheck'] = 0;
189 | /*
190 | | -------------------------------------------------------------------------
191 | | Remember Cookie Prefix Name
192 | | -------------------------------------------------------------------------
193 | | Remember cookie prefix name.
194 | | Default: 'remember' Return: remember_admin_(hash) for admin users / remember_user_(hash) for common users
195 | */
196 | $config['remember_cookie_name'] = 'remember';
197 | /*
198 | | -------------------------------------------------------------------------
199 | | Session Prefix Name
200 | | -------------------------------------------------------------------------
201 | | Admin session prefix name
202 | | Default: 'login' Return: login_admin_(hash) for admin users / login_user_(hash) for users
203 | */
204 | $config['session_name'] = 'login';
205 | /*
206 | | -------------------------------------------------------------------------
207 | | Session Admin Fields
208 | | -------------------------------------------------------------------------
209 | | Admin fields to store on session. You can set a custom name for each item using the second parameter.
210 | | column name(db) => key name(session)
211 | */
212 | $config['session_admin_fields'] = [
213 | 'id' => 'user_id',
214 | 'username' => 'username',
215 | 'email' => 'email',
216 | 'name' => 'name',
217 | 'role_id' => 'role_id', //necessary for group permissions checks
218 | ];
219 | /*
220 | | -------------------------------------------------------------------------
221 | | Session User Fields
222 | | -------------------------------------------------------------------------
223 | | User fields to store on session. You can set a custom name for each item using the second parameter.
224 | | column name(db) => key name(session)
225 | */
226 | $config['session_user_fields'] = [
227 | 'id' => 'id',
228 | 'username' => 'username',
229 | 'email' => 'email',
230 | 'name' => 'name',
231 | ];
232 | /*
233 | | -------------------------------------------------------------------------
234 | | Cache settings
235 | | -------------------------------------------------------------------------
236 | | Caches group and module data for better performance. Updating groups or modules clears the cache automatically.
237 | | Drivers: apc, file, memcached, wincache, redis
238 | */
239 | $config['cache_settings'] = [
240 | 'status' => FALSE, // TRUE,FALSE enable/disable cache
241 | 'time' => 300, //Time To Live, in seconds. 300 = 5 min
242 | 'driver' => 'memcached', //primary driver
243 | 'driver_fallback' => 'file', //fall back driver
244 | ];
--------------------------------------------------------------------------------
/SmartyAcl/language/english/smarty_acl_lang.php:
--------------------------------------------------------------------------------
1 | CI =& get_instance();
38 | //Load necessary libraries and helpers
39 | $this->CI->load->library('session');
40 | $this->CI->load->helper('cookie');
41 | $this->CI->load->helper('url');
42 | //DB Connection
43 | $this->CI->load->database();
44 | //Load lang, config and model
45 | $this->CI->lang->load('smarty_acl');
46 | $this->CI->load->config('smarty_acl', TRUE);
47 | $this->CI->load->model('smarty_acl_model', 'smartyacl_model');
48 | //Get identity
49 | $this->identity = $this->CI->config->item('identity', 'smarty_acl');
50 | //Cache settings
51 | $this->cache_settings = $this->CI->config->item('cache_settings', 'smarty_acl');
52 | if ($this->cache_settings['status'] === TRUE) {
53 | $this->CI->load->driver('cache', array('adapter' => $this->cache_settings['driver'], 'backup' => $this->cache_settings['driver_fallback']));
54 | }
55 | //Set session names
56 | $this->set_session_names();
57 | }
58 |
59 | /**
60 | * Register
61 | *
62 | * @param string $identity
63 | * @param string $password
64 | * @param string $email
65 | * @param array $additional_data
66 | * @param integer $role_id
67 | *
68 | * @return int|array|bool The new user's ID if e-mail activation is disabled or
69 | * Ion-Auth e-mail activation was completed;
70 | * or an array of activation details if CI e-mail validation is enabled;
71 | * or FALSE if the operation failed.
72 | * @throws Exception
73 | */
74 | public function register($identity, $password, $email, $additional_data = [], $role_id = null)
75 | {
76 | //Use defined role or default role
77 | $role_id = $role_id ?? $this->CI->config->item('default_role', 'smarty_acl');
78 | //Create user
79 | $create = $this->CI->smartyacl_model->register($identity, $password, $email, $additional_data, $role_id);
80 |
81 | if ($create) {
82 | //Check for activation email
83 | if ($this->CI->config->item('email_verification', 'smarty_acl')) {
84 | //Generate activation token
85 | return $this->request_activation($email);
86 | }
87 | return TRUE;
88 | }
89 | return FALSE;
90 | }
91 |
92 | /**
93 | * Register user
94 | *
95 | * @param string $identity
96 | * @param string $password
97 | * @param string $email
98 | * @param array $additional_data
99 | *
100 | * @return int|array|bool The new user's ID if e-mail activation is disabled or
101 | * Ion-Auth e-mail activation was completed;
102 | * or an array of activation details if CI e-mail validation is enabled;
103 | * or FALSE if the operation failed.
104 | * @throws Exception
105 | */
106 | public function register_user($identity, $password, $email, $additional_data = [])
107 | {
108 | //Create user
109 | $create = $this->CI->smartyacl_model->register($identity, $password, $email, $additional_data,NULL,FALSE);
110 |
111 | if ($create) {
112 | //Check for activation email
113 | if ($this->CI->config->item('email_verification', 'smarty_acl')) {
114 | //Generate activation token
115 | return $this->request_activation($email,FALSE);
116 | }
117 | return TRUE;
118 | }
119 | return FALSE;
120 | }
121 |
122 | /**
123 | * Request activation
124 | * @param string $email
125 | * @param bool $admin
126 | * @param bool $result_array
127 | * @return bool|array
128 | * @throws Exception
129 | */
130 | private function request_activation($email, $admin = TRUE, $result_array = FALSE)
131 | {
132 | if (!$email) {
133 | return FALSE;
134 | }
135 | //Get user data
136 | if ($admin) {
137 | $user = $this->CI->smartyacl_model->get_admin_by_email($email);
138 | } else {
139 | $user = $this->CI->smartyacl_model->get_user_by_email($email);
140 | }
141 | if (!$user) {
142 | $this->set_error('error_user_not_found');
143 | return FALSE;
144 | }
145 | //Generate activation token
146 | $tokens = $this->generate_selector_validator(20, 40);
147 | //Update user security tokens
148 | $update_tokens = $this->CI->smartyacl_model->security_tokens($user['id'], $tokens,'activation',$admin);
149 | if (!$update_tokens) {
150 | return FALSE;
151 | }
152 | //Get user data
153 | $user_data = [
154 | 'identity' => $user[$this->identity],
155 | 'id' => $user['id'],
156 | 'email' => $user['email'],
157 | 'activation' => $tokens['user_code']
158 | ];
159 | //Check if email_sender is active or request_array was set
160 | if ($result_array || !$this->CI->config->item('email_sender', 'smarty_acl')) {
161 | return $user_data;
162 | }
163 | //Send activation email
164 | return $this->send_activation_email($user_data, $tokens['user_code'], $admin);
165 | }
166 |
167 | /**
168 | * Send activation mail
169 | * @param array $user_data
170 | * @param string $activation
171 | * @param bool $admin
172 | * @return bool
173 | */
174 | public function send_activation_email($user_data, $activation = null, $admin = TRUE)
175 | {
176 | if (!$user_data) {
177 | return FALSE;
178 | }
179 | if ($activation) {
180 | $user_data = array_merge($user_data, ['activation' => $activation]);
181 | }
182 | return $this->send_mail($user_data, 'activation', $admin);
183 | }
184 |
185 | /**
186 | * Send mail to user
187 | * @param array $data
188 | * @param string $type
189 | * @param bool $admin
190 | * @return bool
191 | */
192 | private function send_mail($data, $type, $admin = TRUE)
193 | {
194 | //Load helpers for email template
195 | $this->CI->load->helper('language');
196 | $this->CI->load->helper('url');
197 |
198 | if ($type === 'activation') {
199 | $subject = $this->CI->config->item('sender_name', 'smarty_acl') . ' - ' . $this->CI->lang->line('email_activation_subject');
200 | $view_name = $admin ? 'admin/activate' : 'user/activate';
201 | //Message view template
202 | $message = $this->CI->load->view($this->CI->config->item('email_templates', 'smarty_acl') . $view_name, $data, TRUE);
203 | }
204 | if ($type === 'password') {
205 | $subject = $this->CI->config->item('sender_name', 'smarty_acl') . ' - ' . $this->CI->lang->line('email_forgotten_password_subject');
206 | $view_name = $admin ? 'admin/forgot_password' : 'user/forgot_password';
207 | //Message view template
208 | $message = $this->CI->load->view($this->CI->config->item('email_templates', 'smarty_acl') . $view_name, $data, TRUE);
209 | }
210 | //Load email library
211 | $this->CI->load->library('email');
212 | //Config email
213 | $this->CI->email->initialize($this->CI->config->item('email_settings', 'smarty_acl'));
214 |
215 | $this->CI->email->clear();
216 | $this->CI->email->from($this->CI->config->item('sender_email', 'smarty_acl'), $this->CI->config->item('sender_name', 'smarty_acl'));
217 | $this->CI->email->to($data['email']);
218 | $this->CI->email->subject($subject);
219 | $this->CI->email->message($message);
220 |
221 | if ($this->CI->email->send() === TRUE) {
222 | return TRUE;
223 | }
224 | //Log errors
225 | log_message('ERROR','SmartyAcl Send Mail: '.$this->CI->email->print_debugger(array('headers', 'subject', 'body')));
226 | //Set error message
227 | $this->set_error('error_admin_unable_send_mail');
228 | return FALSE;
229 | }
230 |
231 | /**
232 | * Activate admin user account
233 | * @param integer $user_id
234 | * @param string $code
235 | * @return bool
236 | */
237 | public function activate($user_id, $code)
238 | {
239 | return $this->CI->smartyacl_model->activate($user_id, $code);
240 | }
241 |
242 | /**
243 | * Activate user account
244 | * @param integer $user_id
245 | * @param string $code
246 | * @return bool
247 | */
248 | public function activate_user($user_id, $code)
249 | {
250 | return $this->CI->smartyacl_model->activate($user_id, $code, FALSE);
251 | }
252 |
253 | /**
254 | * Resend activation link
255 | * @param string $email
256 | * @param bool $admin
257 | * @return bool
258 | * @throws Exception
259 | */
260 | public function resend_activation($email, $admin = TRUE)
261 | {
262 | if (!$email) {
263 | return FALSE;
264 | }
265 | return $this->request_activation($email, $admin);
266 | }
267 |
268 | /**
269 | * Forgot Password
270 | * @param string $email
271 | * @param bool $admin
272 | * @return bool
273 | * @throws Exception
274 | */
275 | public function forgotten_password($email, $admin = TRUE)
276 | {
277 | //Generate activation token
278 | $tokens = $this->generate_selector_validator(20, 40);
279 | //Create password reset
280 | $result = $this->CI->smartyacl_model->forgotten_password($email, $tokens, $admin);
281 | //Password reset created
282 | if ($result) {
283 | $data = [
284 | 'identity' => $result[$this->identity],
285 | 'email' => $email,
286 | 'forgotten_password_code' => $tokens['user_code'],
287 | ];
288 | //Send forgot password email
289 | return $this->send_mail($data, 'password', $admin);
290 | }
291 | return FALSE;
292 | }
293 |
294 | /**
295 | * Check forgot password code
296 | * @param string $code
297 | * @param bool $admin
298 | * @return bool|array
299 | */
300 | public function forgotten_password_check($code, $admin = TRUE)
301 | {
302 | //Get user
303 | $user = $this->CI->smartyacl_model->forgotten_password_check($code, $admin);
304 | if (!$user) {
305 | return FALSE;
306 | }
307 | return $user;
308 | }
309 |
310 | /**
311 | * Reset password
312 | * @param array $user
313 | * @param string $email
314 | * @param string $password
315 | * @param bool $admin
316 | * @return bool
317 | */
318 | public function reset_password($user, $email, $password, $admin = TRUE)
319 | {
320 | return $this->CI->smartyacl_model->reset_password($user, $email, $password, $admin);
321 | }
322 |
323 | /**
324 | * Login
325 | * @param string $identity
326 | * @param string $password
327 | * @param bool $remember
328 | * @param bool $admin
329 | * @return bool
330 | */
331 | public function login($identity, $password, $remember = FALSE, $admin = TRUE)
332 | {
333 | return $this->CI->smartyacl_model->login($identity, $password, $remember, $admin);
334 | }
335 |
336 | /**
337 | * Check if user is logged in
338 | * @param bool $admin
339 | * @return bool
340 | */
341 | public function logged_in($admin = TRUE)
342 | {
343 | $logged = $this->CI->smartyacl_model->session_check($admin);
344 | //Try login using remember
345 | if (!$logged) {
346 | return $this->CI->smartyacl_model->login_remembered($admin);
347 | }
348 | return TRUE;
349 | }
350 |
351 | /**
352 | * Logout
353 | * @param bool $admin
354 | * @return bool
355 | */
356 | public function logout($admin = TRUE)
357 | {
358 | return $this->CI->smartyacl_model->logout($admin);
359 | }
360 |
361 | /**
362 | * Get roles
363 | * @param bool $result
364 | * @return object|array
365 | */
366 | public function roles($result = TRUE)
367 | {
368 | //Cache
369 | $cache_name = $this->CI->config->item('tables', 'smarty_acl')['roles'];
370 | if ($this->cache_settings['status']) {
371 | if (!$roles = $this->cache_get($cache_name)) {
372 | $roles = $this->CI->smartyacl_model->roles($result);
373 | $this->cache_save($cache_name, $roles);
374 | }
375 | return $roles;
376 | }
377 | return $this->CI->smartyacl_model->roles($result);
378 | }
379 |
380 | /**
381 | * Create role
382 | * @param array $data
383 | * @return bool
384 | */
385 | public function create_role($data)
386 | {
387 | $created = $this->CI->smartyacl_model->create_role($data);
388 | if ($created) {
389 | //Clear cache
390 | $this->cache_delete($this->CI->config->item('tables', 'smarty_acl')['roles']);
391 | $this->cache_delete('group_permissions');
392 | return TRUE;
393 | }
394 | return FALSE;
395 | }
396 |
397 | /**
398 | * Get role
399 | * @param int $role_id
400 | * @return object|bool
401 | */
402 | public function role($role_id)
403 | {
404 | $roles = $this->roles();
405 | foreach ($roles as $key => $value) {
406 | if ($value->id === $role_id) {
407 | return $value;
408 | }
409 | }
410 | return FALSE;
411 | }
412 |
413 | /**
414 | * Update role
415 | * @param bool $role_id
416 | * @param array $data
417 | * @return bool
418 | */
419 | public function update_role($role_id, $data)
420 | {
421 | $updated = $this->CI->smartyacl_model->update_role($role_id, $data);
422 | if ($updated) {
423 | //Clear cache
424 | $this->cache_delete($this->CI->config->item('tables', 'smarty_acl')['roles']);
425 | $this->cache_delete('group_permissions');
426 | return TRUE;
427 | }
428 | return FALSE;
429 | }
430 |
431 | /**
432 | * Delete role
433 | * @param bool $role_id
434 | * @return bool
435 | */
436 | public function delete_role($role_id)
437 | {
438 | $deleted = $this->CI->smartyacl_model->delete_role($role_id);
439 | if ($deleted) {
440 | //Clear cache
441 | $this->cache_delete($this->CI->config->item('tables', 'smarty_acl')['roles']);
442 | return TRUE;
443 | }
444 | return FALSE;
445 | }
446 |
447 | /**
448 | * Get modules
449 | * @param bool $result
450 | * @return object|array
451 | */
452 | public function modules($result = TRUE)
453 | {
454 | //Cache
455 | if ($this->cache_settings['status']) {
456 | if (!$modules = $this->cache_get($this->CI->config->item('tables', 'smarty_acl')['modules'])) {
457 | $modules = $this->CI->smartyacl_model->modules($result);
458 | $this->cache_save($this->CI->config->item('tables', 'smarty_acl')['modules'], $modules);
459 | }
460 | return $modules;
461 | }
462 | return $this->CI->smartyacl_model->modules($result);
463 | }
464 |
465 | /**
466 | * Get module permissions
467 | * @param int $role_id
468 | * @param bool $result
469 | * @return object|array
470 | */
471 | public function module_permissions($role_id, $result = FALSE)
472 | {
473 | return $this->CI->smartyacl_model->module_permissions($role_id, $result);
474 | }
475 |
476 | /**
477 | * Create module
478 | * @param array $data
479 | * @return bool
480 | */
481 | public function create_module($data)
482 | {
483 | $created = $this->CI->smartyacl_model->create_module($data);
484 | if ($created) {
485 | //Clear cache
486 | $this->cache_delete($this->CI->config->item('tables', 'smarty_acl')['modules']);
487 | return TRUE;
488 | }
489 | return FALSE;
490 | }
491 |
492 | /**
493 | * Get module
494 | * @param int $module_id
495 | * @return object|bool
496 | */
497 | public function module($module_id)
498 | {
499 | $modules = $this->modules();
500 | foreach ($modules as $key => $value) {
501 | if ($value->id === $module_id) {
502 | return $value;
503 | }
504 | }
505 | return FALSE;
506 | }
507 |
508 | /**
509 | * Update module
510 | * @param bool $module_id
511 | * @param array $data
512 | * @return bool
513 | */
514 | public function update_module($module_id, $data)
515 | {
516 | $updated = $this->CI->smartyacl_model->update_module($module_id, $data);
517 | if ($updated) {
518 | //Clear cache
519 | $this->cache_delete($this->CI->config->item('tables', 'smarty_acl')['modules']);
520 | return TRUE;
521 | }
522 | return FALSE;
523 | }
524 |
525 | /**
526 | * Delete module
527 | * @param bool $module_id
528 | * @return bool
529 | */
530 | public function delete_module($module_id)
531 | {
532 | $deleted = $this->CI->smartyacl_model->delete_module($module_id);
533 | if ($deleted) {
534 | //Clear cache
535 | $this->cache_delete($this->CI->config->item('tables', 'smarty_acl')['modules']);
536 | return TRUE;
537 | }
538 | return FALSE;
539 | }
540 |
541 | /**
542 | * Check if user is authorized
543 | * Use on constructor of Controllers, or default method
544 | * @return bool|void
545 | */
546 | public function authorized()
547 | {
548 | //Check if super admin
549 | if($this->CI->session->userdata($this->sess_names['admin'])['role_id'] == 1){
550 | return TRUE;
551 | }
552 | //Get module
553 | $module = $this->CI->uri->segment(2);
554 | //Authorized if user is on admin/ route
555 | if(!$module){
556 | return TRUE;
557 | }
558 | //Check module permissions
559 | $group_permissions = $this->module_authorized($module);
560 | if($group_permissions){
561 | return TRUE;
562 | }
563 | //Unauthorized
564 | return $this->unauthorized_redirect();
565 | }
566 |
567 | /**
568 | * Check if user has module permission access
569 | * Can be used on views
570 | * @param string $module
571 | * @return bool
572 | */
573 | public function module_authorized($module)
574 | {
575 | //Check if super admin
576 | if($this->CI->session->userdata($this->sess_names['admin'])['role_id'] == 1){
577 | return TRUE;
578 | }
579 | //Default class method name
580 | $permission = 'index';
581 | //Get logged in user group permissions
582 | $group_permissions = $this->get_group_permissions_by_role();
583 | if(!$group_permissions){ return show_error($this->errors()); }
584 | //Check authorization
585 | return isset($group_permissions[$module]) && in_array($permission, $group_permissions[$module]);
586 | }
587 |
588 | /**
589 | * Check if user is authorized on module action
590 | * Use on constructor of Controllers, or default method
591 | * @return bool|void
592 | */
593 | public function authorized_action()
594 | {
595 | //Check if super admin
596 | if($this->CI->session->userdata($this->sess_names['admin'])['role_id'] == 1){
597 | return TRUE;
598 | }
599 | //Get module
600 | $action = $this->CI->uri->segment(3);
601 | //Authorized if user is on admin/ route
602 | if($action){
603 | //Check module permissions
604 | $group_permissions = $this->has_permission($action);
605 | if($group_permissions){
606 | return TRUE;
607 | }
608 | }
609 |
610 | //Unauthorized
611 | return $this->unauthorized_redirect();
612 | }
613 |
614 | /**
615 | * Check if user has module action permission access
616 | * Can be used on views
617 | * @param string $permission
618 | * @return bool
619 | */
620 | public function has_permission($permission)
621 | {
622 | //Check if super admin
623 | if($this->CI->session->userdata($this->sess_names['admin'])['role_id'] == 1){
624 | return TRUE;
625 | }
626 | //Default class method name
627 | $module = $this->CI->uri->segment(2);
628 | //Get logged in user group permissions
629 | $group_permissions = $this->get_group_permissions_by_role();
630 | if(!$group_permissions){ return show_error($this->errors()); }
631 | //Check authorization
632 | return isset($group_permissions[$module]) && in_array($permission, $group_permissions[$module]);
633 | }
634 |
635 | /**
636 | * Redirect unauthorized access
637 | * @return void
638 | */
639 | private function unauthorized_redirect()
640 | {
641 | $route = $this->CI->config->item('unauthorized_route', 'smarty_acl');
642 | return redirect($route);
643 | }
644 |
645 | /**
646 | * Get group permissions
647 | * @return array|bool
648 | */
649 | private function get_group_permissions_by_role()
650 | {
651 | $role_id = $this->CI->session->userdata($this->sess_names['admin'])['role_id'];
652 | //Check if user is logged in and have role_id on session array
653 | if(!$role_id){
654 | $this->set_error('error_loggedin_role_id_not_found');
655 | return FALSE;
656 | }
657 | //Cache with role_id to avoid conflict with other role groups
658 | $cache_name = 'group_permissions_'.$role_id;
659 | if ($this->cache_settings['status']) {
660 | if (!$group_permissions = $this->cache_get($cache_name)) {
661 | $group_permissions = $this->CI->smartyacl_model->get_group_permissions_by_role($role_id);
662 | $this->cache_save($cache_name, $group_permissions);
663 | }
664 | return $group_permissions;
665 | }
666 | return $this->CI->smartyacl_model->get_group_permissions_by_role($role_id);
667 | }
668 |
669 | /**
670 | * Get admins
671 | * @param bool $result
672 | * @return object|array
673 | */
674 | public function admins($result = TRUE)
675 | {
676 | return $this->CI->smartyacl_model->admins($result);
677 | }
678 |
679 | /**
680 | * Get users
681 | * @param bool $result
682 | * @return object|array
683 | */
684 | public function users($result = TRUE)
685 | {
686 | return $this->CI->smartyacl_model->users($result);
687 | }
688 |
689 | /**
690 | * Update user account
691 | * @param array $data
692 | * @param int $user_id
693 | * @param bool $admin
694 | * @return bool
695 | */
696 | public function update_user($data, $user_id, $admin = TRUE)
697 | {
698 | //Check for password
699 | if(isset($data['password'])){
700 | $data['password'] = $this->hash_password($data['password']);
701 | }
702 | $updated = $this->CI->smartyacl_model->update_user($data, $user_id, $admin);
703 | if($updated){
704 | //Cache Delete
705 | if ($this->cache_settings['status']) {
706 | $cache_name = $admin ? 'admin_'.$user_id : 'user_'.$user_id;
707 | if ($this->cache_get($cache_name)) {
708 | $this->cache_delete($cache_name);
709 | return TRUE;
710 | }
711 | return TRUE;
712 | }
713 | return TRUE;
714 | }
715 | return FALSE;
716 | }
717 |
718 | /**
719 | * Delete user account
720 | * @param int $user_id
721 | * @param bool $admin
722 | * @return bool
723 | */
724 | public function delete_user($user_id, $admin = TRUE)
725 | {
726 | $deleted = $this->CI->smartyacl_model->delete_user($user_id, $admin);
727 | if($deleted){
728 | //Cache Delete
729 | if ($this->cache_settings['status']) {
730 | $cache_name = $admin ? 'admin_'.$user_id : 'user_'.$user_id;
731 | if ($this->cache_get($cache_name)) {
732 | $this->cache_delete($cache_name);
733 | return TRUE;
734 | }
735 | return TRUE;
736 | }
737 | return TRUE;
738 | }
739 | return FALSE;
740 | }
741 |
742 | /**
743 | * Get user by id
744 | * @param int $user_id
745 | * @param bool $admin
746 | * @return array
747 | */
748 | public function get_user($user_id = NULL, $admin = FALSE)
749 | {
750 | //Set session name
751 | $session_name = $admin ? $this->sess_names['admin'] : $this->sess_names['user'];
752 | //Get logged in user
753 | $loggedin_user = $this->CI->session->userdata($session_name);
754 | //Get user_id or set using session data
755 | $id_user = $user_id ?? $loggedin_user['acl_uid'];
756 | //Set cache name
757 | $cache_name = $admin ? 'admin_'.$id_user : 'user_'.$id_user;
758 | if($admin){
759 | //Cache
760 | if ($this->cache_settings['status'] && isset($loggedin_user) && $loggedin_user['acl_uid'] === $id_user) {
761 | if (!$user_loggedin = $this->cache_get($cache_name)) {
762 | $user_loggedin = $this->CI->smartyacl_model->get_admin_by_id($id_user);
763 | $this->cache_save($cache_name, $user_loggedin);
764 | }
765 | return $user_loggedin;
766 | }
767 | return $this->CI->smartyacl_model->get_admin_by_id($id_user);
768 | }
769 | //Cache
770 | if ($this->cache_settings['status'] && isset($loggedin_user) && $loggedin_user['acl_uid'] === $id_user) {
771 | if (!$user_loggedin = $this->cache_get($cache_name)) {
772 | $user_loggedin = $this->CI->smartyacl_model->get_user_by_id($id_user);
773 | $this->cache_save($cache_name, $user_loggedin);
774 | }
775 | return $user_loggedin;
776 | }
777 | return $this->CI->smartyacl_model->get_user_by_id($id_user);
778 | }
779 |
780 | /**
781 | * Get admin user by id
782 | * @param $user_id
783 | * @return array
784 | */
785 | public function get_admin($user_id= NULL)
786 | {
787 | return $this->get_user($user_id, TRUE);
788 | }
789 |
790 | /**
791 | * Delete cache items
792 | * @param string $item
793 | * @return bool
794 | */
795 | protected function cache_delete($item)
796 | {
797 | if ($this->cache_settings['status']) {
798 | $prefix = $this->CI->config->item('tables', 'smarty_acl')['prefix'];
799 | $name = $prefix . '_' . $item;
800 | return $this->CI->cache->delete($name);
801 | }
802 | return TRUE;
803 | }
804 |
805 | /**
806 | * Save cache items
807 | * @param string $name
808 | * @param string|array $values
809 | * @return bool
810 | */
811 | protected function cache_save($name, $values)
812 | {
813 | if ($this->cache_settings['status']) {
814 | $prefix = $this->CI->config->item('tables', 'smarty_acl')['prefix'];
815 | $name = $prefix . '_' . $name;
816 | return $this->CI->cache->save($name, $values, $this->cache_settings['time']);
817 | }
818 | return TRUE;
819 | }
820 |
821 | /**
822 | * Get cache items
823 | * @param string $name
824 | * @return bool|object
825 | */
826 | protected function cache_get($name)
827 | {
828 | if ($this->cache_settings['status']) {
829 | $prefix = $this->CI->config->item('tables', 'smarty_acl')['prefix'];
830 | $name = $prefix . '_' . $name;
831 | return $this->CI->cache->get($name);
832 | }
833 | return TRUE;
834 | }
835 |
836 | /**
837 | * Generate email/remember tokens and selectors
838 | * @param $selector_size int size of the selector token
839 | * @param $validator_size int size of the validator token
840 | *
841 | * @return array
842 | * selector simple token to retrieve the user (to store in DB)
843 | * validator_hashed token (hashed) to validate the user (to store in DB)
844 | * user_code code to be used user-side (in cookie or URL)
845 | * @throws Exception
846 | */
847 | public function generate_selector_validator($selector_size = 40, $validator_size = 128)
848 | {
849 | // The selector is a simple token to retrieve the user
850 | $selector = $this->random_token($selector_size);
851 |
852 | // The validator will strictly validate the user and should be more complex
853 | $validator = $this->random_token($validator_size);
854 |
855 | // The validator is hashed for storing in DB (avoid session stealing in case of DB leaked)
856 | $validator_hashed = $this->hash_password($validator);
857 |
858 | // The code to be used user-side
859 | $user_code = "$selector.$validator";
860 |
861 | return [
862 | 'selector' => $selector,
863 | 'validator_hashed' => $validator_hashed,
864 | 'user_code' => $user_code,
865 | ];
866 | }
867 |
868 | /**
869 | * Generate a random token
870 | * @param int $result_length
871 | * @return string
872 | * @throws Exception
873 | */
874 | protected function random_token($result_length = 32)
875 | {
876 | if (!$result_length || $result_length <= 8) {
877 | $result_length = 32;
878 | }
879 |
880 | return bin2hex(random_bytes($result_length / 2));
881 | }
882 |
883 | /**
884 | * Get errors
885 | * @return string|array
886 | */
887 | public function errors()
888 | {
889 | return $this->CI->smartyacl_model->errors();
890 | }
891 |
892 | /**
893 | * Get messages
894 | * @return string|array
895 | */
896 | public function messages()
897 | {
898 | return $this->CI->smartyacl_model->messages();
899 | }
900 |
901 | /**
902 | * Set error message
903 | * @param string $error
904 | * @return string
905 | */
906 | public function set_error($error)
907 | {
908 | return $this->CI->smartyacl_model->set_error($error);
909 | }
910 |
911 | /**
912 | * Set message
913 | * @param string $message
914 | * @return string
915 | */
916 | public function set_message($message)
917 | {
918 | return $this->CI->smartyacl_model->set_message($message);
919 | }
920 |
921 | /**
922 | * Set error/message delimiters
923 | * @param int $start
924 | * @param int $end
925 | * @return bool
926 | */
927 | public function set_delimiter($start, $end)
928 | {
929 | return $this->CI->smartyacl_model->set_message_delimiters($start, $end);
930 | }
931 |
932 | /**
933 | * Hash passwords
934 | * @param string $password
935 | * @return string
936 | */
937 | public function hash_password($password)
938 | {
939 | return $this->CI->smartyacl_model->hash_password($password);
940 | }
941 |
942 | /**
943 | * Set session names
944 | */
945 | private function set_session_names()
946 | {
947 | $this->sess_names = $this->CI->smartyacl_model->get_session_names();
948 | }
949 | }
950 |
--------------------------------------------------------------------------------
/SmartyAcl/models/Smarty_acl_model.php:
--------------------------------------------------------------------------------
1 | set_tables();
70 | //Set error/messages delimiters
71 | $this->message_start_delimiter = $this->config->item('message_start_delimiter','smarty_acl');
72 | $this->message_end_delimiter = $this->config->item('message_end_delimiter','smarty_acl');
73 | //Set identity column
74 | $this->identity = $this->config->item('identity','smarty_acl');
75 | //Set default role ID
76 | $this->default_role = $this->config->item('default_role','smarty_acl');
77 | //Set password algo
78 | $this->password_algo = $this->config->item('password_algo','smarty_acl');
79 | //Set session names
80 | $this->session_names = [
81 | 'admin' => $this->config->item('session_name', 'smarty_acl').'_admin_'.sha1(static::class),
82 | 'user' => $this->config->item('session_name', 'smarty_acl').'_user_'.sha1(static::class),
83 | ];
84 | //Set remember cookie names
85 | $this->remember_names = [
86 | 'admin' => $this->config->item('remember_cookie_name', 'smarty_acl').'_admin_'.sha1(static::class),
87 | 'user' => $this->config->item('remember_cookie_name', 'smarty_acl').'_user_'.sha1(static::class),
88 | ];
89 | }
90 |
91 | /**
92 | * Register admin/user
93 | * @param string $identity
94 | * @param string $password
95 | * @param string $email
96 | * @param array $additional_data
97 | * @param integer $role_id
98 | * @param bool $admin
99 | * @return integer(id) or FALSE
100 | */
101 | public function register($identity, $password, $email, $additional_data = [], $role_id = null, $admin = TRUE){
102 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
103 | //Check identity
104 | if($this->user_exists($identity,$admin)){
105 | $this->set_error('register_identity_unavailable');
106 | return FALSE;
107 | }
108 | if($admin){
109 | //Check default role
110 | if(!$role_id || !$this->default_role){
111 | $this->set_error('register_undefined_role');
112 | return FALSE;
113 | }
114 | //Check if role exists
115 | $role_exists = $this->data_exists($this->tables['roles'],'id',$role_id,1);
116 | if(!$role_exists){
117 | $this->set_error('register_invalid_role');
118 | return FALSE;
119 | }
120 | }
121 | // Get IP Address
122 | $ip_address = $this->input->ip_address();
123 | // Hash password
124 | $password = $this->hash_password($password);
125 | //Filter additional fields
126 | $additional = $this->filter_data($table, $additional_data);
127 | //User data
128 | $user_data = [
129 | $this->identity => $identity,
130 | 'password' => $password,
131 | 'email' => $email,
132 | 'ip' => $ip_address,
133 | 'created_at' => date('Y-m-d H:i:s'),
134 | 'updated_at' => date('Y-m-d H:i:s'),
135 | ];
136 | if($admin){
137 | $user_data['role_id'] = $role_id;
138 | }
139 | //Insert on DB
140 | $this->db->insert($table, array_merge($user_data, $additional));
141 | //Get new user ID
142 | $id = $this->db->insert_id();
143 |
144 | return $id ?? FALSE;
145 | }
146 |
147 | /**
148 | * Activate account
149 | * @param integer $user_id
150 | * @param string $code
151 | * @param bool $admin TRUE(admin), FALSE(user)
152 | * @return bool
153 | */
154 | public function activate($user_id, $code, $admin = TRUE)
155 | {
156 | if(!$user_id || !$code){
157 | $this->set_error('activation_invalid_link');
158 | return FALSE;
159 | }
160 | //Retrieve code array
161 | $token = $this->retrieve_code_pair($code);
162 | if(!$token){
163 | $this->set_error('error_invalid_security_token');
164 | return FALSE;
165 | }
166 | //Get user data
167 | $user_data = $this->get_user_by('email_activator',$token['selector'],$admin);
168 | if(!$user_data){
169 | $this->set_error('activation_expired_link');
170 | return FALSE;
171 | }
172 | // Check the hash against the validator
173 | $validate = password_verify($token['validator'], $user_data['email_activator_code']);
174 | if(!$validate){
175 | $this->set_error('activation_invalid_token');
176 | return FALSE;
177 | }
178 | //Activate user
179 | return $this->update_user([
180 | 'email_activator' => NULL,
181 | 'email_activator_code' => NULL,
182 | 'email_verified_at' => date('Y-m-d H:i:s'),
183 | ], $user_id, $admin);
184 | }
185 |
186 | /**
187 | * Forgot Password
188 | * @param string $email
189 | * @param array $token
190 | * @param bool $admin
191 | * @return bool|array
192 | */
193 | public function forgotten_password($email, $token, $admin = TRUE)
194 | {
195 | $type = $admin ? 'admin' : 'user';
196 | //Get user
197 | $user = $admin ? $this->get_admin_by_email($email) : $this->get_user_by_email($email);
198 | if(!$user){
199 | $this->set_error('forgot_password_email_not_found');
200 | return FALSE;
201 | }
202 | //Data
203 | $data = [
204 | 'type' => $type,
205 | 'email' => $email,
206 | 'token' => $token['selector'],
207 | 'token_code' => $token['validator_hashed'],
208 | 'created_at' => date('Y-m-d H:i:s')
209 | ];
210 | //Check if exists
211 | $check = $this->db->where('type',$type)->where('email',$email)->count_all_results($this->tables['password_resets']) > 0;
212 | if($check){
213 | //Update password_resets table
214 | $password_reset = $this->db->update($this->tables['password_resets'], $data, ['type' => $type, 'email' => $email]);
215 | }else{
216 | //Insert on password_resets table
217 | $password_reset = $this->db->insert($this->tables['password_resets'], $data);
218 | }
219 | if(!$password_reset){
220 | $this->set_error('error_create_password_reset_data');
221 | return FALSE;
222 | }
223 | return $user;
224 | }
225 |
226 | /**
227 | * Forgotten password check
228 | * @param string $code
229 | * @param bool $admin
230 | * @return bool|array
231 | */
232 | public function forgotten_password_check($code, $admin = TRUE)
233 | {
234 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
235 | //Retrieve code array
236 | $token = $this->retrieve_code_pair($code);
237 | if(!$token){
238 | $this->set_error('error_invalid_security_token');
239 | return FALSE;
240 | }
241 | //Get password reset data
242 | $password = $this->db->where('token', $token['selector'])->get($this->tables['password_resets'])->row();
243 | if(!$password){
244 | $this->set_error('password_reset_invalid_token');
245 | return FALSE;
246 | }
247 | //Check expired code
248 | $expiration = $this->config->item('forgot_password_expiration', 'smarty_acl');
249 | if($expiration > 0 ){
250 | $now = date_create();
251 | $expire = date_create($password->created_at)->modify('+'.$expiration.' sec');
252 | if ($now > $expire)
253 | {
254 | //Delete expired code
255 | $this->db->delete($this->tables['password_resets'],['token' => $password->token]);
256 | $this->set_error('password_reset_expired_token');
257 | return FALSE;
258 | }
259 | }
260 | // Check the hash against the validator
261 | if (password_verify($token['validator'], $password->token_code))
262 | {
263 | //Get user
264 | $user = $this->db->where('email', $password->email)->get($table)->row_array();
265 | if(!$user){
266 | $this->set_error('error_user_not_found');
267 | return FALSE;
268 | }
269 | return $user;
270 | }
271 | return FALSE;
272 | }
273 |
274 | /**
275 | * Reset password
276 | * @param array $user
277 | * @param string $email
278 | * @param string $password
279 | * @param bool $admin
280 | * @return bool
281 | */
282 | public function reset_password($user, $email, $password, $admin = TRUE)
283 | {
284 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
285 | //Check user exists
286 | $user_exists = $this->data_exists($table, 'email', $user['email']);
287 | if(!$user_exists){
288 | $this->set_error('error_user_not_found');
289 | return FALSE;
290 | }
291 | //Hash password
292 | $new_password = $this->hash_password($password);
293 | //Update user password and email
294 | $update = $this->update_user([
295 | 'email' => $email,
296 | 'password' => $new_password,
297 | 'remember_token' => null, //invalidate remember token
298 | ], $user['id'], $admin);
299 | if(!$update){
300 | $this->set_error('password_reset_failed_update');
301 | return FALSE;
302 | }
303 | //Remove reset password
304 | $reset_password = $this->db->delete($this->tables['password_resets'],[
305 | 'type' => $admin ? 'admin' : 'user',
306 | 'email' => $user['email']
307 | ]);
308 | if(!$reset_password){
309 | $this->set_error('password_reset_failed_delete');
310 | return FALSE;
311 | }
312 | return TRUE;
313 | }
314 |
315 | /**
316 | * Login
317 | * @param string $identity
318 | * @param string $password
319 | * @param bool $remember
320 | * @param bool $admin
321 | * @return bool
322 | */
323 | public function login($identity, $password, $remember = FALSE, $admin = TRUE)
324 | {
325 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
326 | //Count attempts
327 | $attempts = $this->check_attempts($identity, $admin);
328 | if(!$attempts){
329 | return FALSE;
330 | }
331 | //Check multi identity login
332 | $multi = $this->config->item('multi_identity', 'smarty_acl') ? ['email' => $identity] : [$this->identity => $identity];
333 | //Get user
334 | $user_data = $this->db->where($this->identity, $identity)->or_where($multi)->limit(1)->get($table)->row();
335 | //Check role status
336 | if($admin){
337 | //Get role
338 | $role = $this->db->select('status')->where('id',$user_data->role_id)->get($this->tables['roles'])->row();
339 | //Check status
340 | if($role->status==='inactive'){
341 | $this->increase_login_attempts($identity, $admin);
342 | $this->set_error('login_error_role_inactive');
343 | return FALSE;
344 | }
345 | }
346 | if(!$user_data){
347 | $this->increase_login_attempts($identity, $admin);
348 | $this->set_error('login_error_incorrect');
349 | return FALSE;
350 | }
351 | //Check password
352 | $check_password = password_verify($password, $user_data->password);
353 | if(!$check_password){
354 | $this->increase_login_attempts($identity, $admin);
355 | $this->set_error('login_error_incorrect');
356 | return FALSE;
357 | }
358 | //Check email verified
359 | $verified_email = $this->config->item('email_verification', 'smarty_acl');
360 | if($verified_email && !$user_data->email_verified_at){
361 | $this->set_error('login_error_email_unverified');
362 | return FALSE;
363 | }
364 | //Check status
365 | if($user_data->status !== 'active'){
366 | $this->increase_login_attempts($identity, $admin);
367 | if($user_data->status === 'inactive'){
368 | $this->set_error('login_error_account_inactive');
369 | }
370 | if($user_data->status === 'banned'){
371 | $this->set_error('login_error_account_banned');
372 | }
373 | return FALSE;
374 | }
375 | //Create session
376 | $this->create_session($user_data->id, $admin);
377 | //Update user data
378 | $update_user = $this->update_user(['last_login' => date('Y-m-d H:i:s')], $user_data->id, $admin);
379 | if(!$update_user){
380 | $this->set_error('error_update_user_data');
381 | return FALSE;
382 | }
383 | //Clear login attempts
384 | $clear_attempts = $this->clear_loggin_attempts($identity, $admin);
385 | if(!$clear_attempts){
386 | $this->set_error('error_clear_user_attempts');
387 | return FALSE;
388 | }
389 | //Check remember
390 | if($remember){
391 | $this->remember_user($user_data->id, $admin);
392 | }else{
393 | $this->clear_remember_code($user_data->id, $admin);
394 | }
395 | //Regenerate the session (for security purpose: to avoid session fixation)
396 | $this->session->sess_regenerate(FALSE);
397 | return TRUE;
398 | }
399 |
400 | /**
401 | * Remember user
402 | * @param int $user_id
403 | * @param bool $admin
404 | * @return bool
405 | */
406 | public function remember_user($user_id, $admin = TRUE)
407 | {
408 | //Cookie name
409 | $cookie = $admin ? $this->remember_names['admin'] : $this->remember_names['user'];
410 | //Generate tokens
411 | $tokens = $this->smarty_acl->generate_selector_validator();
412 | //Update user tokens
413 | $update_tokens = $this->security_tokens($user_id,$tokens,'remember',$admin);
414 | if(!$update_tokens){
415 | $this->set_error('error_update_security_tokens');
416 | return FALSE;
417 | }
418 | set_cookie([
419 | 'name' => $cookie,
420 | 'value' => $tokens['user_code'],
421 | 'expire' => $this->config->item('session_expire', 'smarty_acl') > 0 ? $this->config->item('session_expire', 'smarty_acl') : 86500
422 | ]);
423 | return TRUE;
424 | }
425 |
426 | /**
427 | * Clear Remember user
428 | * @param int $user_id
429 | * @param bool $admin
430 | * @return bool
431 | */
432 | public function clear_remember_code($user_id, $admin = TRUE)
433 | {
434 | return $this->update_user([
435 | 'remember_token' => NULL,
436 | 'remember_token_code' => NULL],$user_id,$admin);
437 | }
438 |
439 | /**
440 | * Create user session
441 | * @param int $user_id
442 | * @param bool $admin
443 | * @return bool
444 | */
445 | protected function create_session($user_id, $admin = TRUE)
446 | {
447 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
448 | //Fields
449 | $fields = $admin ? $this->config->item('session_admin_fields', 'smarty_acl') : $this->config->item('session_user_fields', 'smarty_acl');
450 | //Filter fields
451 | $field_keys = array_keys($fields);
452 | //Customize Column Names
453 | $custom = implode(', ', array_map(function ($field) use($fields){ return $field.' as '.$fields[$field];},$field_keys));
454 | //Get user with custom data
455 | $user = $this->db->select($custom)->where('id', $user_id)->get($table)->row_array();
456 | //Add last check time and user id with custom key(used by check_session method)
457 | $session_data = array_merge($user, [
458 | 'acl_uid' => $user_id,
459 | 'last_check' => time()
460 | ]);
461 | //Create session
462 | $this->session->set_userdata($admin ? $this->session_names['admin'] : $this->session_names['user'], $session_data);
463 | return TRUE;
464 | }
465 |
466 | /**
467 | * Get group permissions by role_id
468 | * @param int $role_id
469 | * @return array
470 | */
471 | public function get_group_permissions_by_role($role_id)
472 | {
473 | $modules = $this->db
474 | ->where('role_id', $role_id)
475 | ->join($this->tables['module_permissions'] . ' as mp', 'mp.module_id = m.id')
476 | ->get($this->tables['modules'] . ' as m')->result_array();
477 | //Mount easy readable array
478 | $permissions_array = [];
479 | foreach ($modules as $module) {
480 | $permissions_array[$module['controller']][] = $module['permission'];
481 | }
482 | return $permissions_array;
483 | }
484 |
485 | /**
486 | * Clear Login Attempts
487 | * @param string $identity
488 | * @param bool $admin
489 | * @return bool
490 | */
491 | private function clear_loggin_attempts($identity, $admin = TRUE)
492 | {
493 | return $this->db->delete($this->tables['login_attempts'],['type' => $admin ? 'admin' : 'user', 'login' => $identity]);
494 | }
495 |
496 | /**
497 | * Increase Login Attempts
498 | * @param string $identity
499 | * @param bool $admin
500 | * @return bool
501 | */
502 | protected function increase_login_attempts($identity, $admin = true)
503 | {
504 | if ($this->config->item('maximum_login_attempts', 'smarty_acl') > 0)
505 | {
506 | $data = [
507 | 'type' => $admin ? 'admin' : 'user',
508 | 'ip' => $this->input->ip_address(),
509 | 'login' => $identity,
510 | 'created_at' => date('Y-m-d H:i:s')
511 | ];
512 |
513 | return $this->db->insert($this->tables['login_attempts'], $data);
514 | }
515 | return FALSE;
516 | }
517 |
518 | /**
519 | * Check login attempts
520 | * @param string $identity
521 | * @param bool $admin
522 | * @return bool
523 | */
524 | protected function check_attempts($identity, $admin = true)
525 | {
526 | //Get configs
527 | $max = $this->config->item('maximum_login_attempts', 'smarty_acl');
528 | $lockout_time = $this->config->item('lockout_time', 'smarty_acl');
529 | $time = date_create()->modify('-'.$lockout_time.' sec');
530 | //Check if max attempts equals 0(disabled)
531 | if($max === 0) {
532 | return TRUE;
533 | }
534 | //Count attempts
535 | $attempts = $this->rows_count($this->tables['login_attempts'],['login' => $identity, 'type' => $admin ? 'admin' : 'user', 'created_at >' => $time->format('Y-m-d H:i:s')]);
536 | if($attempts >= $max){
537 | $this->set_error('login_error_timeout');
538 | return FALSE;
539 | }
540 | return TRUE;
541 | }
542 |
543 | /**
544 | * Check session for logged in user
545 | * @param bool $admin
546 | * @return bool
547 | */
548 | public function session_check($admin = TRUE)
549 | {
550 | //Get session name
551 | $session_name = $admin ? $this->session_names['admin'] : $this->session_names['user'];
552 | $session = $this->session->userdata($session_name);
553 | //Check session exists
554 | if(!$session){
555 | return FALSE;
556 | }
557 | //Get recheck
558 | $recheck = $this->config->item('session_recheck', 'smarty_acl');
559 | if($recheck === 0){
560 | return TRUE;
561 | }
562 | //Recheck session
563 | if($session['last_check'] + $recheck > time()){
564 | return TRUE;
565 | }
566 | $table_name = $admin ? $this->tables['admins'] : $this->tables['users'];
567 | $find_where = ['id' => $session['acl_uid'], 'status' => 'active'];
568 | if($this->config->item('email_verification', 'smarty_acl')){
569 | $find_where['email_verified_at !='] = NULL;
570 | }
571 | //Find user
572 | $user = $this->db->where($find_where)->limit(1)->count_all_results($table_name);
573 | if(!$user){
574 | //Unset session
575 | $this->session->unset_userdata($session_name);
576 | return FALSE;
577 | }
578 | return TRUE;
579 | }
580 |
581 | /**
582 | * Login user using remember cookie
583 | * @param bool $admin
584 | * @return bool
585 | */
586 | public function login_remembered($admin = TRUE)
587 | {
588 | //Get cookie name
589 | $cookie_name = $admin ? $this->remember_names['admin'] : $this->remember_names['user'];
590 | $cookie = get_cookie($cookie_name);
591 | if(!$cookie){
592 | return FALSE;
593 | }
594 | //Get token
595 | $token = $this->retrieve_code_pair($cookie);
596 | if(!$token){
597 | $this->set_error('error_invalid_security_token');
598 | return FALSE;
599 | }
600 | //Check user exists and delete cookie
601 | $table_name = $admin ? $this->tables['admins'] : $this->tables['users'];
602 | $find_where = ['remember_token' => $token['selector'], 'status' => 'active'];
603 | if($this->config->item('email_verification', 'smarty_acl')){
604 | $find_where['email_verified_at !='] = NULL;
605 | }
606 | //Find user
607 | $user = $this->db->where($find_where)->limit(1)->get($table_name)->row();
608 | if(!$user){
609 | $this->set_error('error_user_not_found');
610 | delete_cookie($cookie_name);
611 | return FALSE;
612 | }
613 | //Validate token
614 | if (!password_verify($token['validator'], $user->remember_token_code))
615 | {
616 | return FALSE;
617 | }
618 | //Set session
619 | $this->create_session($user->id, $admin);
620 | //Update user data
621 | $update_user = $this->update_user(['last_login' => date('Y-m-d H:i:s')], $user->id, $admin);
622 | if(!$update_user){
623 | $this->set_error('error_update_user_data');
624 | return FALSE;
625 | }
626 | //Clear login attempts
627 | $clear_attempts = $this->clear_loggin_attempts($user->{$this->identity}, $admin);
628 | if(!$clear_attempts){
629 | $this->set_error('error_clear_user_attempts');
630 | return FALSE;
631 | }
632 | // Regenerate the session (for security purpose: to avoid session fixation)
633 | $this->session->sess_regenerate(FALSE);
634 | return TRUE;
635 | }
636 |
637 | /**
638 | * Logout user
639 | * @param bool $admin
640 | * @return bool
641 | */
642 | public function logout($admin = TRUE)
643 | {
644 | //Get session name
645 | $session_name = $admin ? $this->session_names['admin'] : $this->session_names['user'];
646 | //Delete user session
647 | $this->session->unset_userdata($session_name);
648 | //Get cookie name
649 | $cookie_name = $admin ? $this->remember_names['admin'] : $this->remember_names['user'];
650 | //Delete cookie
651 | delete_cookie($cookie_name);
652 | //Delete remember tokens
653 | $this->clear_remember_code($this->session->userdata($session_name)['acl_uid'],$admin);
654 | // Destroy the session
655 | $this->session->sess_destroy();
656 | return true;
657 | }
658 |
659 | /**
660 | * Get Roles
661 | * @param bool $result
662 | * @return object|array
663 | */
664 | public function roles($result = TRUE){
665 | $results = $result ? 'result' : 'result_array';
666 | return $this->db->get($this->tables['roles'])->{$results}();
667 | }
668 |
669 | /**
670 | * Create role
671 | * @param array $data
672 | * @return bool
673 | */
674 | public function create_role($data)
675 | {
676 | $fields = $this->filter_data($this->tables['roles'],$data);
677 | $create = $this->db->insert($this->tables['roles'],$fields);
678 | if(!$create){
679 | $this->set_error('roles_error_unable_create');
680 | return FALSE;
681 | }
682 | //Assign permissions
683 | $new_role = $this->db->insert_id();
684 | return $this->permissions_to_role($new_role,$data['permissions']);
685 | }
686 |
687 | /**
688 | * Update roles
689 | * @param int $role_id
690 | * @param array $data
691 | * @return bool
692 | */
693 | public function update_role($role_id,$data)
694 | {
695 | $fields = $this->filter_data($this->tables['roles'],$data);
696 | //Check superadmin role, avoid disable
697 | if($role_id == 1){
698 | $fields['status'] = 'active';
699 | }
700 | $update = $this->db->update($this->tables['roles'],$fields,['id' => $role_id]);
701 | if(!$update){
702 | $this->set_error('roles_error_unable_update');
703 | return FALSE;
704 | }
705 | //Assign permissions
706 | return $this->permissions_to_role($role_id,$data['permissions']);
707 | }
708 |
709 | /**
710 | * Delete role
711 | * @param int $role_id
712 | * @return bool
713 | */
714 | public function delete_role($role_id)
715 | {
716 | //Check superadmin role
717 | if($role_id == 1){
718 | $this->set_error('roles_error_notallowed_delete');
719 | return FALSE;
720 | }
721 | //Move users to default role
722 | $default_role = $this->config->item('default_role', 'smarty_acl');
723 | $this->db->where('role_id',$role_id)->update($this->tables['admins'],['role_id' => $default_role]);
724 | //Delete role
725 | return $this->db->delete($this->tables['roles'],['id' => $role_id]);
726 | }
727 | /**
728 | * Assoc permissions to role
729 | * @param int $role_id
730 | * @param array $permissions
731 | * @return bool
732 | */
733 | private function permissions_to_role($role_id,$permissions)
734 | {
735 | //Get module ids
736 | $get_modules = array_keys($permissions);
737 | //Delete module permissions not checked
738 | $this->db->where('role_id', $role_id)->where_not_in('module_id',$get_modules)->delete($this->tables['module_permissions']);
739 | foreach ($permissions as $module => $permission){
740 | //Get permissions values
741 | $get_permissions = array_values($permission);
742 | if($get_permissions){
743 | $this->db->where(['module_id' => $module, 'role_id' => $role_id])->where_not_in('permission',$get_permissions)->delete($this->tables['module_permissions']);
744 | //Create
745 | array_map(function ($a) use($module, $role_id) {
746 | //Check if exists
747 | $exists = $this->db->where(['module_id' => $module, 'role_id' => $role_id, 'permission' => $a])->count_all_results($this->tables['module_permissions']) > 0;
748 | if(!$exists) {
749 | //Insert permission
750 | $this->db->where(['module_id' => $module, 'role_id' => $role_id])->where('permission !=', $a)->insert($this->tables['module_permissions'], ['role_id' => $role_id, 'module_id' => $module, 'permission' => $a]);
751 | return ['module_id' => $module, 'permission' => $a];
752 | }
753 | }, $permission);
754 | }
755 | }
756 | return TRUE;
757 | }
758 |
759 | /**
760 | * Get modules
761 | * @param bool $result
762 | * @return object|array
763 | */
764 | public function modules($result = TRUE)
765 | {
766 | $results = $result ? 'result' : 'result_array';
767 | return $this->db->get($this->tables['modules'])->{$results}();
768 | }
769 |
770 | /**
771 | * Get admins
772 | * @param bool $result
773 | * @return object|array
774 | */
775 | public function admins($result = TRUE)
776 | {
777 | $results = $result ? 'result' : 'result_array';
778 | return $this->db->select('r.name as group_name, u.*')
779 | ->join($this->tables['admins'].' as u', 'u.role_id = r.id','inner')
780 | ->get($this->tables['roles'].' as r')->{$results}();
781 | }
782 |
783 | /**
784 | * Get users
785 | * @param bool $result
786 | * @return object|array
787 | */
788 | public function users($result = TRUE)
789 | {
790 | $results = $result ? 'result' : 'result_array';
791 | return $this->db->get($this->tables['users'])->{$results}();
792 | }
793 |
794 | /**
795 | * Get module permissions
796 | * @param int $role_id
797 | * @param bool $result
798 | * @return object|array
799 | */
800 | public function module_permissions($role_id, $result = TRUE)
801 | {
802 | $results = $result ? 'result' : 'result_array';
803 | $permissions = $this->db->where('role_id',$role_id)->get($this->tables['module_permissions'])->{$results}();
804 | $result = [];
805 | if($permissions) {
806 | foreach ($permissions as $p) {
807 | $result[$p['module_id']][$p['id']] = $p['permission'];
808 | }
809 | }
810 | return $result;
811 | }
812 |
813 | /**
814 | * Create module
815 | * @param array $data
816 | * @return bool
817 | */
818 | public function create_module($data)
819 | {
820 | $fields = $this->filter_data($this->tables['modules'],$data);
821 | //Remove whitespaces
822 | $permissions = str_replace(' ','',$data['permissions']);
823 | //Convert to json array
824 | $fields['permissions'] = json_encode(explode(',',$permissions));
825 | $create = $this->db->insert($this->tables['modules'],$fields);
826 | if(!$create){
827 | $this->set_error('modules_error_unable_create');
828 | return FALSE;
829 | }
830 | return TRUE;
831 | }
832 |
833 | /**
834 | * Update module
835 | * @param int $module_id
836 | * @param array $data
837 | * @return bool
838 | */
839 | public function update_module($module_id, $data)
840 | {
841 | $fields = $this->filter_data($this->tables['modules'],$data);
842 | //Remove whitespaces
843 | $permissions = str_replace(' ','',$data['permissions']);
844 | //Convert to json array
845 | $fields['permissions'] = json_encode(explode(',',$permissions));
846 | $update = $this->db->update($this->tables['modules'],$fields,['id' => $module_id]);
847 | if(!$update){
848 | $this->set_error('modules_error_unable_update');
849 | return FALSE;
850 | }
851 | return TRUE;
852 | }
853 |
854 | /**
855 | * Delete module
856 | * @param int $module_id
857 | * @return bool
858 | */
859 | public function delete_module($module_id)
860 | {
861 | //Delete module
862 | return $this->db->delete($this->tables['modules'],['id' => $module_id]);
863 | }
864 |
865 | /**
866 | * Get session name
867 | * @return array
868 | */
869 | public function get_session_names()
870 | {
871 | return $this->session_names;
872 | }
873 |
874 | /**
875 | * Get admin user by ID
876 | * @param string $user_id
877 | * @return array
878 | */
879 | public function get_admin_by_id($user_id = NULL)
880 | {
881 | //Get session name
882 | $session_name = $this->session_names['admin'];
883 | $user = $user_id ?? $this->session->userdata($session_name)['acl_uid'];
884 | return $this->get_user_by('id', $user);
885 | }
886 |
887 | /**
888 | * Get admin user by email
889 | * @param string $user_email
890 | * @return array
891 | */
892 | public function get_admin_by_email($user_email)
893 | {
894 | return $this->get_user_by('email', $user_email);
895 | }
896 |
897 | /**
898 | * Get user by ID
899 | * @param string $user_id
900 | * @return array
901 | */
902 | public function get_user_by_id($user_id = NULL)
903 | {
904 | //Get session name
905 | $session_name = $this->session_names['user'];
906 | $user = $user_id ?? $this->session->userdata($session_name)['acl_uid'];
907 | return $this->get_user_by('id', $user, FALSE);
908 | }
909 |
910 | /**
911 | * Get user by email
912 | * @param string $user_email
913 | * @return array
914 | */
915 | public function get_user_by_email($user_email)
916 | {
917 | return $this->get_user_by('email', $user_email, FALSE);
918 | }
919 |
920 | /**
921 | * Get user or admin by id
922 | * @param string $field
923 | * @param string $value
924 | * @param bool $admin
925 | * @return array
926 | */
927 | private function get_user_by($field, $value, $admin = true)
928 | {
929 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
930 | //Add group name on array
931 | if($admin){
932 | return $this->db->select('r.name as group_name, u.*')
933 | ->where('u.'.$field, $value)
934 | ->join($table.' as u', 'u.role_id = r.id','inner')
935 | ->get($this->tables['roles'].' as r')->row_array();
936 | }
937 | return $this->db->where($field, $value)->get($table)->row_array();
938 | }
939 |
940 | /**
941 | * Update user security tokens
942 | * @param integer $user_id
943 | * @param array $tokens
944 | * @param string $type activation / remember
945 | * @param bool $role admin / user
946 | * @return bool
947 | */
948 | public function security_tokens($user_id, $tokens, $type = 'activation', $role = TRUE)
949 | {
950 | $table = $role ? $this->tables['admins'] : $this->tables['users'];
951 | if($type==='remember'){
952 | $data = [
953 | 'remember_token' => $tokens['selector'],
954 | 'remember_token_code' => $tokens['validator_hashed']
955 | ];
956 | }else{
957 | $data = [
958 | 'email_activator' => $tokens['selector'],
959 | 'email_activator_code' => $tokens['validator_hashed']
960 | ];
961 | //Check if user already verified email
962 | $check = $this->db->where('email_verified_at !=',null)->where('id',$user_id)->count_all_results($table) > 0;
963 | if($check){
964 | $this->set_error('error_email_already_confirmed');
965 | return FALSE;
966 | }
967 | }
968 | $update = $this->update_user($data, $user_id, $role);
969 | if(!$update){
970 | $this->set_error('error_update_security_tokens');
971 | return FALSE;
972 | }
973 | return TRUE;
974 | }
975 |
976 | /**
977 | * Update user data
978 | * @param array $data
979 | * @param integer $user_id
980 | * @param bool $admin
981 | * @return bool
982 | */
983 | public function update_user($data, $user_id, $admin = true)
984 | {
985 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
986 | $new_data = array_merge($data, ['updated_at' => date('Y-m-d H:i:s')]);
987 | $updated = $this->db->update($table, $new_data, ['id' => $user_id]);
988 | if(!$updated){
989 | $this->set_error('error_updating_user_account');
990 | return FALSE;
991 | }
992 | return TRUE;
993 | }
994 |
995 | /**
996 | * Delete user
997 | * @param int $user_id
998 | * @param bool $admin
999 | * @return bool
1000 | */
1001 | public function delete_user($user_id, $admin = TRUE)
1002 | {
1003 | $table = $admin ? $this->tables['admins'] : $this->tables['users'];
1004 | //Set session name
1005 | $session_name = $admin ? $this->session_names['admin'] : $this->session_names['user'];
1006 | //Legged in user
1007 | $loggedin_user = $this->session->userdata($session_name);
1008 | //Avoid delete yourself
1009 | if($user_id == $loggedin_user['acl_uid']){
1010 | $this->set_error('error_user_delete_yourself');
1011 | return FALSE;
1012 | }
1013 | //Admin checks
1014 | if($admin){
1015 | $get_admin = $this->get_admin_by_id($user_id);
1016 | $get_loggedin_admin = $this->get_admin_by_id($loggedin_user['acl_uid']);
1017 | //Avoid other roles delete superadmin
1018 | if($get_admin['role_id'] == 1 && $get_loggedin_admin['role_id'] != 1){
1019 | $this->set_error('error_admin_delete_superadmin');
1020 | return FALSE;
1021 | }
1022 | }
1023 | //Delete user
1024 | return $this->db->delete($table,['id' => $user_id]);
1025 | }
1026 |
1027 | /**
1028 | * Return validator code pair for activation and remember me
1029 | * @param string $code
1030 | * @return array|bool
1031 | */
1032 | private function retrieve_code_pair($code)
1033 | {
1034 | if($code){
1035 | $token = explode('.',$code);
1036 | // Check tokens
1037 | if (count($token) === 2)
1038 | {
1039 | return [
1040 | 'selector' => $token[0],
1041 | 'validator' => $token[1]
1042 | ];
1043 | }
1044 | }
1045 | return FALSE;
1046 | }
1047 |
1048 | /**
1049 | * Filter additional fields array
1050 | * @param string $table
1051 | * @param array $data
1052 | * @return array
1053 | */
1054 | protected function filter_data($table, $data)
1055 | {
1056 | $filtered_data = [];
1057 | $columns = $this->db->list_fields($table);
1058 |
1059 | if (is_array($data))
1060 | {
1061 | foreach ($columns as $column)
1062 | {
1063 | if (array_key_exists($column, $data)) {
1064 | $filtered_data[$column] = $data[$column];
1065 | }
1066 | }
1067 | }
1068 | return $filtered_data;
1069 | }
1070 |
1071 | /**
1072 | * Create a password hash
1073 | * @param string $password
1074 | * @return string
1075 | */
1076 | public function hash_password($password)
1077 | {
1078 | return password_hash($password, $this->password_algo);
1079 | }
1080 |
1081 | /**
1082 | * Check if user already registered
1083 | * @param string $identity
1084 | * @param bool $type admin / user
1085 | * @return bool
1086 | */
1087 | public function user_exists($identity, $type = TRUE){
1088 | if(!$identity){
1089 | return FALSE;
1090 | }
1091 | $table = $type ? $this->tables['admins'] : $this->tables['users'];
1092 | return $this->data_exists($table,$this->identity,$identity,1);
1093 | }
1094 |
1095 | /**
1096 | * Check if data exists on a table
1097 | * @param $table_name string
1098 | * @param $field string
1099 | * @param $value string
1100 | * @param $limit integer
1101 | * @return bool
1102 | */
1103 | private function data_exists($table_name, $field, $value, $limit = null)
1104 | {
1105 | return $this->db->where($field, $value)
1106 | ->limit($limit)
1107 | ->count_all_results($table_name) > 0;
1108 | }
1109 |
1110 | /**
1111 | * Count rows
1112 | * @param string $table
1113 | * @param array $params
1114 | * @return integer
1115 | */
1116 | protected function rows_count($table, $params = null)
1117 | {
1118 | if($params){
1119 | $this->db->where($params);
1120 | }
1121 | return $this->db->get($table)->num_rows();
1122 | }
1123 |
1124 | /**
1125 | * Set table names with/without prefix
1126 | */
1127 | private function set_tables()
1128 | {
1129 | $tables = $this->config->item('tables','smarty_acl');
1130 | $prefix = $tables['prefix'] ? $tables['prefix'].'_' : '';
1131 | $this->tables = [
1132 | 'admins' => $tables['admins'],
1133 | 'users' => $tables['users'],
1134 | 'roles' => $prefix.$tables['roles'],
1135 | 'modules' => $prefix.$tables['modules'],
1136 | 'module_permissions' => $prefix.$tables['module_permissions'],
1137 | 'password_resets' => $prefix.$tables['password_resets'],
1138 | 'login_attempts' => $prefix.$tables['login_attempts'],
1139 | ];
1140 | }
1141 |
1142 | /**
1143 | * Set error message
1144 | * @param string $error
1145 | * @return string
1146 | */
1147 | public function set_error($error)
1148 | {
1149 | $this->errors[] = $error;
1150 | return $error;
1151 | }
1152 |
1153 | /**
1154 | * Get error messages
1155 | * @param bool $translate
1156 | * @return string|array
1157 | */
1158 | public function errors($translate = TRUE)
1159 | {
1160 | return $this->get_errors_messages(TRUE, $translate);
1161 | }
1162 |
1163 | /**
1164 | * Set a message
1165 | * @param string $message
1166 | * @return string
1167 | */
1168 | public function set_message($message)
1169 | {
1170 | $this->messages[] = $message;
1171 | return $message;
1172 | }
1173 |
1174 | /**
1175 | * Get messages
1176 | * @param bool $translate
1177 | * @return string|array
1178 | */
1179 | public function messages($translate = TRUE)
1180 | {
1181 | return $this->get_errors_messages(FALSE, $translate);
1182 | }
1183 |
1184 | /**
1185 | * Return errors or message response
1186 | * @param bool $error
1187 | * @param bool $translate
1188 | * @return string|array messages/errors translated or messages/errors as array
1189 | */
1190 | private function get_errors_messages($error = TRUE, $translate = TRUE)
1191 | {
1192 | $values = $error ? $this->errors : $this->messages;
1193 | if ($translate)
1194 | {
1195 | $_output = [];
1196 | foreach ($values as $value)
1197 | {
1198 | $errorLang = $this->lang->line($value) ? $this->lang->line($value) : '##' . $value . '##';
1199 | $_output[] = $this->message_start_delimiter . $errorLang . $this->message_end_delimiter;
1200 | }
1201 | if(count($_output) >= 2){
1202 | return $_output;
1203 | }
1204 | return $_output[0];
1205 | }
1206 | return $values;
1207 | }
1208 | /**
1209 | * Set the message delimiters
1210 | * @param string $start_delimiter
1211 | * @param string $end_delimiter
1212 | * @return bool
1213 | */
1214 | public function set_message_delimiters($start_delimiter, $end_delimiter)
1215 | {
1216 | $this->message_start_delimiter = $start_delimiter;
1217 | $this->message_end_delimiter = $end_delimiter;
1218 | return TRUE;
1219 | }
1220 | }
--------------------------------------------------------------------------------
/SmartyAcl/views/auth/email/admin/activate.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/SmartyAcl/views/auth/email/admin/forgot_password.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/SmartyAcl/views/auth/email/user/activate.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/SmartyAcl/views/auth/email/user/forgot_password.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/database.sql:
--------------------------------------------------------------------------------
1 | -- phpMyAdmin SQL Dump
2 | -- version 5.0.2
3 | -- https://www.phpmyadmin.net/
4 | --
5 | -- Host: laradock_mysql_1
6 | -- Tempo de geração: 25/05/2020 às 20:46
7 | -- Versão do servidor: 5.7.30
8 | -- Versão do PHP: 7.4.5
9 |
10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
11 | START TRANSACTION;
12 | SET time_zone = "+00:00";
13 |
14 |
15 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
16 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
17 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
18 | /*!40101 SET NAMES utf8mb4 */;
19 |
20 | --
21 | -- Banco de dados: `smarty_smartyacl`
22 | --
23 |
24 | -- --------------------------------------------------------
25 |
26 | --
27 | -- Estrutura para tabela `acl_login_attempts`
28 | --
29 |
30 | CREATE TABLE `acl_login_attempts` (
31 | `id` int(11) NOT NULL,
32 | `type` enum('admin','user') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'admin',
33 | `login` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
34 | `ip` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
35 | `created_at` timestamp NULL DEFAULT NULL
36 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
37 |
38 | -- --------------------------------------------------------
39 |
40 | --
41 | -- Estrutura para tabela `acl_modules`
42 | --
43 |
44 | CREATE TABLE `acl_modules` (
45 | `id` int(11) UNSIGNED NOT NULL,
46 | `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
47 | `controller` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
48 | `permissions` json NOT NULL
49 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
50 |
51 | --
52 | -- Despejando dados para a tabela `acl_modules`
53 | --
54 |
55 | INSERT INTO `acl_modules` (`id`, `name`, `controller`, `permissions`) VALUES
56 | (1, 'Dashboard', 'admin', '[\"index\", \"edit\", \"delete\", \"create\"]'),
57 | (2, 'Manage Modules', 'modules', '[\"index\", \"edit\", \"delete\", \"create\"]'),
58 | (3, 'Manage Roles', 'roles', '[\"index\", \"edit\", \"delete\", \"create\"]'),
59 | (4, 'Manage Admins', 'admins', '[\"index\", \"edit\", \"delete\", \"create\"]'),
60 | (5, 'Manage Users', 'users', '[\"index\", \"edit\", \"delete\", \"create\"]');
61 |
62 | -- --------------------------------------------------------
63 |
64 | --
65 | -- Estrutura para tabela `acl_module_permissions`
66 | --
67 |
68 | CREATE TABLE `acl_module_permissions` (
69 | `id` int(11) UNSIGNED NOT NULL,
70 | `role_id` int(11) UNSIGNED NOT NULL,
71 | `module_id` int(11) UNSIGNED NOT NULL,
72 | `permission` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL
73 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
74 |
75 | --
76 | -- Despejando dados para a tabela `acl_module_permissions`
77 | --
78 |
79 | INSERT INTO `acl_module_permissions` (`id`, `role_id`, `module_id`, `permission`) VALUES
80 | (1, 1, 1, 'edit'),
81 | (2, 1, 1, 'delete'),
82 | (3, 1, 2, 'edit'),
83 | (4, 1, 3, 'edit'),
84 | (5, 1, 3, 'delete'),
85 | (6, 1, 1, 'create'),
86 | (7, 1, 2, 'delete'),
87 | (8, 1, 3, 'create'),
88 | (9, 1, 1, 'index'),
89 | (10, 1, 2, 'index'),
90 | (11, 1, 3, 'index'),
91 | (12, 2, 1, 'index'),
92 | (13, 3, 1, 'index'),
93 | (14, 3, 2, 'index'),
94 | (15, 3, 3, 'index'),
95 | (16, 1, 2, 'create'),
96 | (17, 1, 4, 'index'),
97 | (18, 1, 4, 'edit'),
98 | (19, 1, 4, 'delete'),
99 | (20, 1, 4, 'create'),
100 | (21, 1, 5, 'index'),
101 | (22, 1, 5, 'edit'),
102 | (23, 1, 5, 'delete'),
103 | (24, 1, 5, 'create'),
104 | (25, 2, 5, 'edit'),
105 | (26, 2, 5, 'delete'),
106 | (27, 2, 5, 'create'),
107 | (28, 3, 4, 'index'),
108 | (29, 2, 5, 'index'),
109 | (30, 2, 3, 'index'),
110 | (31, 2, 4, 'index'),
111 | (32, 2, 4, 'delete'),
112 | (33, 3, 5, 'index'),
113 | (34, 3, 1, 'edit');
114 |
115 | -- --------------------------------------------------------
116 |
117 | --
118 | -- Estrutura para tabela `acl_password_resets`
119 | --
120 |
121 | CREATE TABLE `acl_password_resets` (
122 | `type` enum('admin','user') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'admin',
123 | `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
124 | `token` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
125 | `token_code` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
126 | `created_at` timestamp NULL DEFAULT NULL
127 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
128 |
129 | -- --------------------------------------------------------
130 |
131 | --
132 | -- Estrutura para tabela `acl_roles`
133 | --
134 |
135 | CREATE TABLE `acl_roles` (
136 | `id` int(11) UNSIGNED NOT NULL,
137 | `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
138 | `status` enum('active','inactive') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active'
139 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
140 |
141 | --
142 | -- Despejando dados para a tabela `acl_roles`
143 | --
144 |
145 | INSERT INTO `acl_roles` (`id`, `name`, `status`) VALUES
146 | (1, 'Super Admin', 'active'),
147 | (2, 'Admin', 'inactive'),
148 | (3, 'Demo', 'active');
149 |
150 | -- --------------------------------------------------------
151 |
152 | --
153 | -- Estrutura para tabela `admins`
154 | --
155 |
156 | CREATE TABLE `admins` (
157 | `id` int(11) UNSIGNED NOT NULL,
158 | `username` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
159 | `password` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
160 | `name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
161 | `email` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
162 | `role_id` int(11) NOT NULL,
163 | `status` enum('inactive','active','banned') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
164 | `last_login` timestamp NULL DEFAULT NULL,
165 | `ip` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
166 | `email_verified_at` timestamp NULL DEFAULT NULL,
167 | `email_activator` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
168 | `email_activator_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
169 | `remember_token` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
170 | `remember_token_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
171 | `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
172 | `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
173 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
174 |
175 | --
176 | -- Despejando dados para a tabela `admins`
177 | --
178 |
179 | INSERT INTO `admins` (`id`, `username`, `password`, `name`, `email`, `role_id`, `status`, `last_login`, `ip`, `email_verified_at`, `email_activator`, `email_activator_code`, `remember_token`, `remember_token_code`, `created_at`, `updated_at`) VALUES
180 | (1, 'admin', '$2y$10$TmJKG3yV8o7kCycAdQI0/.7jJ5uhO3RC9pyJOMlbFHmbEzUk8JMfu', 'Name Last Name', 'admin@admin.com', 1, 'active', '2020-05-25 20:05:36', '172.19.0.1', '2020-05-21 17:19:04', NULL, NULL, NULL, NULL, '2020-05-17 19:30:21', '2020-05-25 20:05:36');
181 |
182 | -- --------------------------------------------------------
183 |
184 | --
185 | -- Estrutura para tabela `users`
186 | --
187 |
188 | CREATE TABLE `users` (
189 | `id` int(11) UNSIGNED NOT NULL,
190 | `username` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
191 | `password` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
192 | `name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
193 | `email` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
194 | `status` enum('inactive','active','banned') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'active',
195 | `last_login` timestamp NULL DEFAULT NULL,
196 | `ip` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
197 | `email_verified_at` timestamp NULL DEFAULT NULL,
198 | `email_activator` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
199 | `email_activator_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
200 | `remember_token` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
201 | `remember_token_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
202 | `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
203 | `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
204 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
205 |
206 | --
207 | -- Índices de tabelas apagadas
208 | --
209 |
210 | --
211 | -- Índices de tabela `acl_login_attempts`
212 | --
213 | ALTER TABLE `acl_login_attempts`
214 | ADD PRIMARY KEY (`id`);
215 |
216 | --
217 | -- Índices de tabela `acl_modules`
218 | --
219 | ALTER TABLE `acl_modules`
220 | ADD PRIMARY KEY (`id`);
221 |
222 | --
223 | -- Índices de tabela `acl_module_permissions`
224 | --
225 | ALTER TABLE `acl_module_permissions`
226 | ADD PRIMARY KEY (`id`),
227 | ADD KEY `module_id` (`module_id`),
228 | ADD KEY `role_id` (`role_id`);
229 |
230 | --
231 | -- Índices de tabela `acl_password_resets`
232 | --
233 | ALTER TABLE `acl_password_resets`
234 | ADD KEY `password_resets_email_index` (`email`);
235 |
236 | --
237 | -- Índices de tabela `acl_roles`
238 | --
239 | ALTER TABLE `acl_roles`
240 | ADD PRIMARY KEY (`id`);
241 |
242 | --
243 | -- Índices de tabela `admins`
244 | --
245 | ALTER TABLE `admins`
246 | ADD PRIMARY KEY (`id`),
247 | ADD UNIQUE KEY `username` (`username`),
248 | ADD UNIQUE KEY `email` (`email`),
249 | ADD UNIQUE KEY `email_activator` (`email_activator`),
250 | ADD UNIQUE KEY `remember_token` (`remember_token`);
251 |
252 | --
253 | -- Índices de tabela `users`
254 | --
255 | ALTER TABLE `users`
256 | ADD PRIMARY KEY (`id`),
257 | ADD UNIQUE KEY `username` (`username`),
258 | ADD UNIQUE KEY `email` (`email`),
259 | ADD UNIQUE KEY `email_activator` (`email_activator`),
260 | ADD UNIQUE KEY `remember_token` (`remember_token`);
261 |
262 | --
263 | -- AUTO_INCREMENT de tabelas apagadas
264 | --
265 |
266 | --
267 | -- AUTO_INCREMENT de tabela `acl_login_attempts`
268 | --
269 | ALTER TABLE `acl_login_attempts`
270 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
271 |
272 | --
273 | -- AUTO_INCREMENT de tabela `acl_modules`
274 | --
275 | ALTER TABLE `acl_modules`
276 | MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
277 |
278 | --
279 | -- AUTO_INCREMENT de tabela `acl_module_permissions`
280 | --
281 | ALTER TABLE `acl_module_permissions`
282 | MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=35;
283 |
284 | --
285 | -- AUTO_INCREMENT de tabela `acl_roles`
286 | --
287 | ALTER TABLE `acl_roles`
288 | MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;
289 |
290 | --
291 | -- AUTO_INCREMENT de tabela `admins`
292 | --
293 | ALTER TABLE `admins`
294 | MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=48;
295 |
296 | --
297 | -- AUTO_INCREMENT de tabela `users`
298 | --
299 | ALTER TABLE `users`
300 | MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
301 |
302 | --
303 | -- Restrições para dumps de tabelas
304 | --
305 |
306 | --
307 | -- Restrições para tabelas `acl_module_permissions`
308 | --
309 | ALTER TABLE `acl_module_permissions`
310 | ADD CONSTRAINT `acl_module_permissions_ibfk_1` FOREIGN KEY (`module_id`) REFERENCES `acl_modules` (`id`) ON DELETE CASCADE,
311 | ADD CONSTRAINT `acl_module_permissions_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `acl_roles` (`id`) ON DELETE CASCADE;
312 | COMMIT;
313 |
314 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
315 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
316 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
317 |
--------------------------------------------------------------------------------