1: <?php
  2: 
  3: defined('BASEPATH') OR exit('No direct script access allowed');
  4: 
  5: 
  6: require APPPATH . '/libraries/REST_Controller.php';
  7: 
  8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18: 
 19: class Key extends REST_Controller {
 20: 
 21:     protected $methods = [
 22:             'index_put' => ['level' => 10, 'limit' => 10],
 23:             'index_delete' => ['level' => 10],
 24:             'level_post' => ['level' => 10],
 25:             'regenerate_post' => ['level' => 10],
 26:         ];
 27: 
 28:      29:  30:  31:  32:  33: 
 34:     public function index_put()
 35:     {
 36:         
 37:         $key = $this->_generate_key();
 38: 
 39:         
 40:         $level = $this->put('level') ? $this->put('level') : 1;
 41:         $ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1;
 42: 
 43:         
 44:         if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits]))
 45:         {
 46:             $this->response([
 47:                 'status' => TRUE,
 48:                 'key' => $key
 49:             ], REST_Controller::HTTP_CREATED); 
 50:         }
 51:         else
 52:         {
 53:             $this->response([
 54:                 'status' => FALSE,
 55:                 'message' => 'Could not save the key'
 56:             ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); 
 57:         }
 58:     }
 59: 
 60:      61:  62:  63:  64:  65: 
 66:     public function index_delete()
 67:     {
 68:         $key = $this->delete('key');
 69: 
 70:         
 71:         if (!$this->_key_exists($key))
 72:         {
 73:             
 74:             $this->response([
 75:                 'status' => FALSE,
 76:                 'message' => 'Invalid API key'
 77:             ], REST_Controller::HTTP_BAD_REQUEST); 
 78:         }
 79: 
 80:         
 81:         $this->_delete_key($key);
 82: 
 83:         
 84:         $this->response([
 85:             'status' => TRUE,
 86:             'message' => 'API key was deleted'
 87:             ], REST_Controller::HTTP_NO_CONTENT); 
 88:     }
 89: 
 90:      91:  92:  93:  94:  95: 
 96:     public function level_post()
 97:     {
 98:         $key = $this->post('key');
 99:         $new_level = $this->post('level');
100: 
101:         
102:         if (!$this->_key_exists($key))
103:         {
104:             
105:             $this->response([
106:                 'status' => FALSE,
107:                 'message' => 'Invalid API key'
108:             ], REST_Controller::HTTP_BAD_REQUEST); 
109:         }
110: 
111:         
112:         if ($this->_update_key($key, ['level' => $new_level]))
113:         {
114:             $this->response([
115:                 'status' => TRUE,
116:                 'message' => 'API key was updated'
117:             ], REST_Controller::HTTP_OK); 
118:         }
119:         else
120:         {
121:             $this->response([
122:                 'status' => FALSE,
123:                 'message' => 'Could not update the key level'
124:             ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); 
125:         }
126:     }
127: 
128:     129: 130: 131: 132: 133: 
134:     public function suspend_post()
135:     {
136:         $key = $this->post('key');
137: 
138:         
139:         if (!$this->_key_exists($key))
140:         {
141:             
142:             $this->response([
143:                 'status' => FALSE,
144:                 'message' => 'Invalid API key'
145:             ], REST_Controller::HTTP_BAD_REQUEST); 
146:         }
147: 
148:         
149:         if ($this->_update_key($key, ['level' => 0]))
150:         {
151:             $this->response([
152:                 'status' => TRUE,
153:                 'message' => 'Key was suspended'
154:             ], REST_Controller::HTTP_OK); 
155:         }
156:         else
157:         {
158:             $this->response([
159:                 'status' => FALSE,
160:                 'message' => 'Could not suspend the user'
161:             ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); 
162:         }
163:     }
164: 
165:     166: 167: 168: 169: 170: 
171:     public function regenerate_post()
172:     {
173:         $old_key = $this->post('key');
174:         $key_details = $this->_get_key($old_key);
175: 
176:         
177:         if (!$key_details)
178:         {
179:             
180:             $this->response([
181:                 'status' => FALSE,
182:                 'message' => 'Invalid API key'
183:             ], REST_Controller::HTTP_BAD_REQUEST); 
184:         }
185: 
186:         
187:         $new_key = $this->_generate_key();
188: 
189:         
190:         if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits]))
191:         {
192:             
193:             $this->_update_key($old_key, ['level' => 0]);
194: 
195:             $this->response([
196:                 'status' => TRUE,
197:                 'key' => $new_key
198:             ], REST_Controller::HTTP_CREATED); 
199:         }
200:         else
201:         {
202:             $this->response([
203:                 'status' => FALSE,
204:                 'message' => 'Could not save the key'
205:             ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); 
206:         }
207:     }
208: 
209:     
210: 
211:     private function _generate_key()
212:     {
213:         do
214:         {
215:             
216:             $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
217: 
218:             
219:             if ($salt === FALSE)
220:             {
221:                 $salt = hash('sha256', time() . mt_rand());
222:             }
223: 
224:             $new_key = substr($salt, 0, config_item('rest_key_length'));
225:         }
226:         while ($this->_key_exists($new_key));
227: 
228:         return $new_key;
229:     }
230: 
231:     
232: 
233:     private function _get_key($key)
234:     {
235:         return $this->db
236:             ->where(config_item('rest_key_column'), $key)
237:             ->get(config_item('rest_keys_table'))
238:             ->row();
239:     }
240: 
241:     private function _key_exists($key)
242:     {
243:         return $this->db
244:             ->where(config_item('rest_key_column'), $key)
245:             ->count_all_results(config_item('rest_keys_table')) > 0;
246:     }
247: 
248:     private function _insert_key($key, $data)
249:     {
250:         $data[config_item('rest_key_column')] = $key;
251:         $data['date_created'] = function_exists('now') ? now() : time();
252: 
253:         return $this->db
254:             ->set($data)
255:             ->insert(config_item('rest_keys_table'));
256:     }
257: 
258:     private function _update_key($key, $data)
259:     {
260:         return $this->db
261:             ->where(config_item('rest_key_column'), $key)
262:             ->update(config_item('rest_keys_table'), $data);
263:     }
264: 
265:     private function _delete_key($key)
266:     {
267:         return $this->db
268:             ->where(config_item('rest_key_column'), $key)
269:             ->delete(config_item('rest_keys_table'));
270:     }
271: 
272: }
273: