16 |
rodolico |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
/*
|
|
|
4 |
Copyright (c) 2021, Daily Data, Inc. Redistribution and use in
|
|
|
5 |
source and binary forms, with or without modification, are permitted
|
|
|
6 |
provided that the following conditions are met:
|
|
|
7 |
|
|
|
8 |
* Redistributions of source code must retain the above copyright
|
|
|
9 |
notice, this list of conditions and the following disclaimer.
|
|
|
10 |
* Redistributions in binary form must reproduce the above copyright
|
|
|
11 |
notice, this list of conditions and the following disclaimer in the
|
|
|
12 |
documentation and/or other materials provided with the distribution.
|
|
|
13 |
|
|
|
14 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
15 |
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
16 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
17 |
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
18 |
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
19 |
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
20 |
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
21 |
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
22 |
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
23 |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
24 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
25 |
|
|
|
26 |
*/
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
// Let's make sure we have the Users class loaded.
|
|
|
30 |
require_once( 'Users.class.php' );
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
/**
|
|
|
34 |
* User Permissions Login class
|
|
|
35 |
*
|
|
|
36 |
* IMPORTANT: Requires a data source. See UsersDataSourceMySQLi.class.php
|
|
|
37 |
* for code which provides this for MySQLi
|
|
|
38 |
*
|
|
|
39 |
* UsersPermissions extends the Users class to include boolean
|
|
|
40 |
* permissions.
|
|
|
41 |
*
|
|
|
42 |
* @author R. W. Rodolico <rodo@unixservertech.com>
|
|
|
43 |
*
|
21 |
rodolico |
44 |
* @version 1.0.0 (beta)
|
16 |
rodolico |
45 |
* @copyright 2021 Daily Data, Inc.
|
|
|
46 |
*
|
|
|
47 |
*/
|
|
|
48 |
|
|
|
49 |
class UsersPermissions extends Users {
|
|
|
50 |
|
20 |
rodolico |
51 |
/**
|
|
|
52 |
* Extends Users::_construct
|
|
|
53 |
*
|
|
|
54 |
* Adds additional fields needed for permissions. However, this
|
|
|
55 |
* information is not actually used in the code, but is included here
|
|
|
56 |
* for documentation and/or possible extensions
|
|
|
57 |
*
|
|
|
58 |
* @param string[] $customFields Array of definition modifications to underlying structure
|
|
|
59 |
*/
|
16 |
rodolico |
60 |
public function __construct( $customFields = array() ) {
|
37 |
rodolico |
61 |
$permissions = array(
|
|
|
62 |
// taken from jsfiddle.net/pynhA/2/
|
|
|
63 |
'html input fields' => array(
|
|
|
64 |
'permissions' => "<li><input type='checkbox' id='%s' name='%s' title='%s' ~~%s~~><label for='%s'>%s</label>\n</li>\n",
|
|
|
65 |
'permissions block' => "<fieldset class='login_permissions_group'>\n<legend>%s</legend>\n<ul class='login_permissions'>\n%s\n</ul></fieldset>"
|
|
|
66 |
)
|
|
|
67 |
);
|
20 |
rodolico |
68 |
$this->configuration = array_merge_recursive( $this->configuration, $permissions );
|
16 |
rodolico |
69 |
parent::__construct( $customFields );
|
|
|
70 |
} // constructor
|
17 |
rodolico |
71 |
|
|
|
72 |
|
20 |
rodolico |
73 |
/**
|
|
|
74 |
* Extends Users::validate
|
|
|
75 |
*
|
|
|
76 |
* Loads permissions if user was validated
|
|
|
77 |
*
|
|
|
78 |
* @param string $username
|
|
|
79 |
* @param string $password
|
|
|
80 |
* @param usersPermissionsDataSource $connection
|
|
|
81 |
*
|
|
|
82 |
* @returns boolean true if username/password are correct
|
|
|
83 |
*/
|
17 |
rodolico |
84 |
protected function validate( $username, $password, $connection ) {
|
|
|
85 |
if ( parent::validate( $username, $password, $connection ) ) {
|
|
|
86 |
$this->data['permissions'] = $connection->getPermissions( $this->data['id'] );
|
20 |
rodolico |
87 |
return true;
|
17 |
rodolico |
88 |
}
|
20 |
rodolico |
89 |
return false;
|
17 |
rodolico |
90 |
}
|
|
|
91 |
|
20 |
rodolico |
92 |
/**
|
|
|
93 |
* Extends Users::editScreen
|
|
|
94 |
*
|
|
|
95 |
* Adds permissions in div of class category
|
|
|
96 |
*
|
|
|
97 |
* @param usersPermissionsDataSource $connection
|
|
|
98 |
*
|
|
|
99 |
* @returns string HTML display screen
|
|
|
100 |
*/
|
17 |
rodolico |
101 |
public function editScreen( $connection ) {
|
|
|
102 |
$divDef = "<div class='category'>\n";
|
|
|
103 |
$return = array();
|
|
|
104 |
$return[] = parent::editScreen( $connection );
|
|
|
105 |
if ( $this->isAdmin() ) {
|
|
|
106 |
$values = $connection->getFullPermissions( $this->workingOn['id'] );
|
|
|
107 |
$category = array();
|
|
|
108 |
foreach ( $values as $thisEntry ) {
|
|
|
109 |
$field = $thisEntry['permission'];
|
37 |
rodolico |
110 |
$temp = sprintf( $this->configuration['html input fields']['permissions'],
|
|
|
111 |
$this->configuration['input prefix'] . $field, // id
|
|
|
112 |
$this->configuration['input prefix'] . $field, // name
|
|
|
113 |
'Place a check here to allow user to ' . $thisEntry['description'], // title
|
|
|
114 |
$field, // replaced with 'checked' if set
|
|
|
115 |
$this->configuration['input prefix'] . $field, // for=
|
|
|
116 |
$thisEntry['description'] // label
|
17 |
rodolico |
117 |
);
|
|
|
118 |
|
|
|
119 |
$category[$thisEntry['category']][] = preg_replace( "/~~$field~~/", $thisEntry['value'] ? 'checked' : '', $temp );
|
|
|
120 |
}
|
|
|
121 |
|
|
|
122 |
foreach ( $category as $name => $entries ) {
|
37 |
rodolico |
123 |
$return[] = sprintf( $this->configuration['html input fields']['permissions block'],
|
|
|
124 |
$name, // fieldset legend
|
|
|
125 |
implode( "\n", $entries ) // all the entries from first block
|
|
|
126 |
);
|
17 |
rodolico |
127 |
}
|
|
|
128 |
}
|
|
|
129 |
return implode( "\n", $return );
|
|
|
130 |
}
|
|
|
131 |
|
20 |
rodolico |
132 |
/**
|
|
|
133 |
* Adds/Updates existing record
|
|
|
134 |
*
|
|
|
135 |
* Extending Users::addEdit by updating the permissions
|
|
|
136 |
*
|
|
|
137 |
* @param usersPermissionsDataSource $connection
|
|
|
138 |
*
|
|
|
139 |
* @returns string Message saying whether the update/insert worked
|
|
|
140 |
*/
|
17 |
rodolico |
141 |
protected function addEdit( $connection ) {
|
|
|
142 |
$return = parent::addEdit( $connection );
|
|
|
143 |
$data = array();
|
|
|
144 |
// now we process all of the permissions
|
|
|
145 |
if ( $return != 'Error' ) {
|
21 |
rodolico |
146 |
if ( $this->workingOn['id'] == -1 ) {
|
|
|
147 |
$newUserID = $connection->getUserID( $_REQUEST['admin_login'] );
|
|
|
148 |
}
|
17 |
rodolico |
149 |
foreach ( $this->workingOn['permissions'] as $name => $value ) {
|
|
|
150 |
$htmlFieldName = $this->configuration['input prefix'] . $name;
|
19 |
rodolico |
151 |
// if a new user, the permission is whatever is in the form
|
|
|
152 |
if ( $this->workingOn['id'] == -1 && isset( $_REQUEST[$htmlFieldName] ) ) {
|
|
|
153 |
$data[$name] = 1;
|
|
|
154 |
// otherwise, if it is not a new user, only do an update if it has changed
|
|
|
155 |
} elseif ( $this->workingOn['id'] > 0 && isset( $_REQUEST[$htmlFieldName] ) != $this->workingOn['permissions'][$name] ) {
|
17 |
rodolico |
156 |
$data[$name] = isset( $_REQUEST[$htmlFieldName] ) ? 1 : 0;
|
|
|
157 |
}
|
|
|
158 |
} // foreach
|
21 |
rodolico |
159 |
$connection->updatePermissions( ($this->workingOn['id'] == -1 ? $newUserID : $this->workingOn['id'] ),$data );
|
17 |
rodolico |
160 |
} // if not an error
|
|
|
161 |
return $return;
|
|
|
162 |
} // addEdit
|
18 |
rodolico |
163 |
|
20 |
rodolico |
164 |
/**
|
|
|
165 |
* Initializes $this->workingOn
|
|
|
166 |
*
|
|
|
167 |
* This is a modification to Users::initWorkingOn to add permissions
|
|
|
168 |
*/
|
19 |
rodolico |
169 |
protected function initWorkingOn( $connection, $id ) {
|
|
|
170 |
parent::initWorkingOn( $connection, $id );
|
|
|
171 |
if ( ! isset( $this->workingOn['permissions'] ) ) {
|
|
|
172 |
$this->workingOn['permissions'] = $connection->getPermissions( $id );
|
|
|
173 |
}
|
|
|
174 |
}
|
20 |
rodolico |
175 |
|
|
|
176 |
/**
|
|
|
177 |
* returns boolean as to whether the user has the passed in permission
|
|
|
178 |
*
|
|
|
179 |
* If user is an admin, they automatically have all permissions, otherwise
|
|
|
180 |
* we check for the permission. NOTE: the existence of a permission
|
|
|
181 |
* is not validated. If a permission does not exist, will return false
|
|
|
182 |
* for anyone but an admin
|
|
|
183 |
*
|
|
|
184 |
* @param string $permission short form of permission
|
|
|
185 |
* @returns boolean
|
|
|
186 |
*/
|
|
|
187 |
public function isAuthorized ( $permission ) {
|
|
|
188 |
return $this->isAdmin() || $this->data['permissions'][$permission];
|
|
|
189 |
}
|
16 |
rodolico |
190 |
|
20 |
rodolico |
191 |
/**
|
|
|
192 |
* Adds a permission to the permissions table
|
|
|
193 |
*
|
|
|
194 |
* This simply adds a permission to the permissions table, adding the
|
|
|
195 |
* category if it doesn't exist already. Since this is already written
|
|
|
196 |
* in usersPermissionsDataSource, we simply call it.
|
|
|
197 |
*
|
|
|
198 |
* @parameter string $category Category to place the permission into
|
|
|
199 |
* @parameter string $name The short name of the permission
|
|
|
200 |
* @parameter string $description The long (display) name for the permission
|
|
|
201 |
* @parameter boolean $defaultValue The default value for the permission
|
|
|
202 |
*/
|
|
|
203 |
public function addPermission ( $connection, $category, $name, $description, $defaultValue = 0 ) {
|
|
|
204 |
$connection->addPermission ( $category, $name, $description, $defaultValue = 0 );
|
|
|
205 |
}
|
33 |
rodolico |
206 |
|
|
|
207 |
/**
|
|
|
208 |
* returns the array of permissions
|
|
|
209 |
*
|
|
|
210 |
* The keys are the keyname, the value is true or false
|
|
|
211 |
*
|
|
|
212 |
* @return boolean[]
|
|
|
213 |
*/
|
|
|
214 |
|
|
|
215 |
public function getPermissionList() {
|
|
|
216 |
return $this->data['permissions'] ?? array();
|
|
|
217 |
}
|
19 |
rodolico |
218 |
|
16 |
rodolico |
219 |
}
|
|
|
220 |
|
|
|
221 |
?>
|