├── .gitignore
├── .codeclimate.yml
├── documentation
├── resources
│ ├── sort.png
│ ├── footer.png
│ ├── resize.png
│ ├── collapsed.png
│ ├── inherit.png
│ ├── tree-last.png
│ ├── tree-cleaner.png
│ ├── tree-hasnext.png
│ ├── tree-vertical.png
│ └── style.css
├── elementlist.js
├── package-CodeIgniter.html
├── package-CodeIgniter.Libraries.html
├── 404.html
├── package-None.html
├── package-CodeIgniter.Rest.html
├── index.html
├── class-Rest_server.html
├── source-class-Rest_server.html
├── class-Welcome.html
├── source-class-Welcome.html
├── class-Example.html
├── source-class-Example.html
└── class-Key.html
├── application
├── libraries
│ ├── jwt
│ │ ├── ExpiredException.php
│ │ ├── BeforeValidException.php
│ │ ├── SignatureInvalidException.php
│ │ └── JWT.php
│ ├── index.html
│ └── Format.php
├── config
│ ├── index.html
│ └── routes.php
├── language
│ ├── index.html
│ ├── bulgarian
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── dutch
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── english
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── french
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── german
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── indonesia
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── italian
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── romanian
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── spanish
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── turkish
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── serbian_cyr
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── serbian_lat
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── traditional-chinese
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── portuguese-brazilian
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ ├── simplified-chinese
│ │ ├── index.html
│ │ └── rest_controller_lang.php
│ └── greek
│ │ └── rest_controller_lang.php
├── views
│ ├── index.html
│ ├── welcome_message.php
│ └── rest_server.php
└── controllers
│ ├── index.html
│ ├── api
│ ├── index.html
│ ├── Jwt.php
│ ├── Example.php
│ └── Key.php
│ ├── Rest_server.php
│ └── Welcome.php
├── composer.json
├── LICENSE
├── CHANGELOG.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | vendor
3 | .idea
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | exclude_paths:
2 | - "documentation/"
3 | - "application/language/"
--------------------------------------------------------------------------------
/documentation/resources/sort.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/sort.png
--------------------------------------------------------------------------------
/documentation/resources/footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/footer.png
--------------------------------------------------------------------------------
/documentation/resources/resize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/resize.png
--------------------------------------------------------------------------------
/documentation/resources/collapsed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/collapsed.png
--------------------------------------------------------------------------------
/documentation/resources/inherit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/inherit.png
--------------------------------------------------------------------------------
/documentation/resources/tree-last.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/tree-last.png
--------------------------------------------------------------------------------
/documentation/resources/tree-cleaner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/tree-cleaner.png
--------------------------------------------------------------------------------
/documentation/resources/tree-hasnext.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/tree-hasnext.png
--------------------------------------------------------------------------------
/documentation/resources/tree-vertical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aiamk/codeigniter-restserver/HEAD/documentation/resources/tree-vertical.png
--------------------------------------------------------------------------------
/application/libraries/jwt/ExpiredException.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/controllers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/libraries/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/controllers/api/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/bulgarian/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/dutch/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/english/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/french/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/german/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/indonesia/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/italian/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/romanian/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/spanish/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/turkish/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/serbian_cyr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/serbian_lat/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/traditional-chinese/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/portuguese-brazilian/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/language/simplified-chinese/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 403 Forbidden
5 |
6 |
7 |
8 | Directory access is forbidden.
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/application/controllers/Rest_server.php:
--------------------------------------------------------------------------------
1 | load->helper('url');
10 |
11 | $this->load->view('rest_server');
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "REST Server for the CodeIgniter framework",
3 | "name": "chriskacerguis/codeigniter-restserver",
4 | "type": "project",
5 | "homepage": "https://github.com/chriskacerguis/codeigniter-restserver",
6 | "authors": [
7 | {
8 | "name": "Chris Kacerguis",
9 | "role": "Developer"
10 | }
11 | ],
12 | "license": "MIT",
13 | "support": {
14 | "source": "https://github.com/chriskacerguis/codeigniter-restserver"
15 | }
16 | }
--------------------------------------------------------------------------------
/application/controllers/Welcome.php:
--------------------------------------------------------------------------------
1 |
19 | * @see https://codeigniter.com/user_guide/general/urls.html
20 | */
21 | public function index()
22 | {
23 | $this->load->helper('url');
24 |
25 | $this->load->view('welcome_message');
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/application/language/simplified-chinese/rest_controller_lang.php:
--------------------------------------------------------------------------------
1 | my_controller/index
50 | | my-controller/my-method -> my_controller/my_method
51 | */
52 | $route['default_controller'] = 'welcome';
53 | $route['404_override'] = '';
54 | $route['translate_uri_dashes'] = TRUE;
55 |
56 | /*
57 | | -------------------------------------------------------------------------
58 | | Sample REST API Routes
59 | | -------------------------------------------------------------------------
60 | */
61 | $route['api/example/users/(:num)'] = 'api/example/users/id/$1'; // Example 4
62 | $route['api/example/users/(:num)(\.)([a-zA-Z0-9_-]+)(.*)'] = 'api/example/users/id/$1/format/$3$4'; // Example 8
63 |
--------------------------------------------------------------------------------
/documentation/package-CodeIgniter.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Package CodeIgniter
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
67 |
68 |
69 |
70 |
71 | Overview
72 |
73 |
74 | Package
75 |
76 | Class
77 |
78 |
80 |
82 |
83 |
84 |
85 |
Package CodeIgniter
86 |
87 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/documentation/package-CodeIgniter.Libraries.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Package CodeIgniter\Libraries
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
72 |
73 |
74 |
75 |
76 | Overview
77 |
78 |
79 | Package
80 |
81 | Class
82 |
83 |
85 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | Classes summary
96 |
97 | REST_Controller
98 | CodeIgniter Rest Controller
99 | A fully RESTful server implementation for CodeIgniter using one library, one config file and one controller.
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Changelog:
2 | ===========
3 |
4 | ### UNRELEASED
5 | * Added support for CodeIgniter controller's index methods (index_GET, index_POST...)
6 | * Added exceptions handling when the method could not be found
7 |
8 | ### 2.7.2
9 |
10 | * Added $this->query() in which query parameters can now be obtained regardless of whether a GET request is sent or not
11 | * Added doc comments added to functions
12 | * Added HTTP status constants e.g. REST_Controller::HTTP_OK
13 | * Added new CSV formatting function
14 | * Fixed numerous bug fixes
15 | * Updated API calls limit can be based on API key, routed url or method name
16 | * Updated documentation
17 | * Updated examples (thanks @ivantcholakov and @lagaisse)
18 | * Updated many functions by re-writing (thanks @softwarespot)
19 | * Updated performance increase
20 |
21 | ### 2.7.0
22 |
23 | * Added Blacklist IP option
24 | * Added controller based access controls
25 | * Added support for OPTIONS, PATCH, and HEAD (from boh1996)
26 | * Added logging of the time it takes for a request (rtime column in DB)
27 | * Changed DB schemas to use InnoDB, not MyISAM
28 | * Updated Readme to reflect new developer (Chris Kacerguis)
29 |
30 | ### 2.6.2
31 |
32 | * Update CodeIgniter files to 2.1.3
33 | * Fixed issue #165
34 |
35 | ### 2.6.1
36 |
37 | * Update CodeIgniter files to 2.1.2
38 | * Log Table support for IPv6 & NULL parameters
39 | * Abstract out the processes of firing a controller method within _remap() to an separate method
40 | * Moved GET, POST, PUT, and DELETE parsing to separate methods, allowing them to be overridden as needed
41 | * Small bug-fix for a PHP 5.3 strlen error
42 | * Fixed some PHP 5.4 warnings
43 | * Fix for bug in Format.php's to_html() which failed to detect if $data was really a multidimensional array.
44 | * Fix for empty node on XML output format, for false = 0, true = 1.
45 |
46 | ### 2.6.0
47 |
48 | * Added loads of PHPDoc comments.
49 | * Response where method doesn't exist is now "HTTP 405 Method Not Allowed", not "HTTP 404 Not Found".
50 | * Compatible with PHP 5.4.
51 | * Added support for gzip compression.
52 | * Fix the apache\_request\_header function with CGI.
53 | * Fixed up correctly .foo extensions to work when get arguments provided.
54 | * Allows method emulation via X-HTTP-Method-Override
55 | * Support for Backbone.emulateHTTP improved.
56 | * Combine both URI segment and GET params instead of using one or the other
57 | * Separate each piece of the WWW-Authenticate header for digest requests with a comma.
58 | * Added IP white-list option.
59 |
60 | ### 2.5
61 |
62 | * Instead of just seeing item, item, item, the singular version of the base-node will be used if possible. [Example](http://d.pr/RS46).
63 | * Re-factored to use the Format library, which will soon be merged with CodeIgniter.
64 | * Fixed Limit bug (limit of 5 would allow 6 requests).
65 | * Added logging for invalid API key requests.
66 | * Changed serialize to serialized.
67 |
--------------------------------------------------------------------------------
/documentation/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Page not found
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
78 |
79 |
80 |
81 |
82 | Overview
83 |
84 |
85 | Package
86 |
87 | Class
88 |
89 |
91 |
93 |
94 |
95 |
96 |
Page not found
97 |
The requested page could not be found.
98 |
You have probably clicked on a link that is outdated and points to a page that does not exist any more or you have made an typing error in the address.
99 |
To continue please try to find requested page in the menu, or use search field on the top.
100 |
101 |
102 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/documentation/package-None.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | No package
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
74 |
75 |
76 |
77 |
78 | Overview
79 |
80 |
81 | Package
82 |
83 | Class
84 |
85 |
87 |
89 |
90 |
91 |
92 |
No package
93 |
94 |
95 |
96 |
97 | Classes summary
98 |
99 | Format
100 | Format class
101 | Help convert between various formats such as XML, JSON, CSV, etc.
102 |
103 |
104 | Rest_server
105 |
106 |
107 |
108 | Welcome
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/documentation/package-CodeIgniter.Rest.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Package CodeIgniter\Rest
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
73 |
74 |
75 |
76 |
77 | Overview
78 |
79 |
80 | Package
81 |
82 | Class
83 |
84 |
86 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | Classes summary
97 |
98 | Example
99 | This is an example of a few basic user interaction methods you could use
100 | all done with a hardcoded array
101 |
102 |
103 | Key
104 | Keys Controller
105 | This is a basic Key Management REST controller to make and delete keys
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/documentation/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Overview
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
76 |
77 |
78 |
79 |
80 | Overview
81 |
82 | Package
83 |
84 | Class
85 |
86 |
88 |
90 |
91 |
92 |
93 |
Overview
94 |
95 |
96 |
97 |
120 |
121 |
122 |
123 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/application/views/welcome_message.php:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 | Welcome to CodeIgniter
10 |
11 |
70 |
71 |
72 |
73 |
74 |
Welcome to CodeIgniter!
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
The page you are looking at is being generated dynamically by CodeIgniter.
85 |
86 |
If you would like to edit this page you'll find it located at:
87 |
application/views/welcome_message.php
88 |
89 |
The corresponding controller for this page is found at:
90 |
application/controllers/Welcome.php
91 |
92 |
93 |
If you are exploring CodeIgniter for the very first time, you should start by reading the User Guide .
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/documentation/class-Rest_server.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Class Rest_server
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
74 |
75 |
76 |
77 |
78 | Overview
79 |
80 |
81 | Package
82 |
83 | Class
84 |
85 |
87 |
89 |
90 |
91 |
92 |
Class Rest_server
93 |
94 |
95 |
96 |
97 |
98 | CI_Controller
99 |
100 |
101 |
102 |
103 |
104 | Rest_server
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
126 |
127 |
128 |
129 |
130 | Methods summary
131 |
132 |
133 |
134 | public
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
#
143 |
index ( )
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
--------------------------------------------------------------------------------
/documentation/source-class-Rest_server.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | File controllers/Rest_server.php
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
78 |
79 |
80 |
81 |
82 | Overview
83 |
84 |
85 | Package
86 |
87 | Class
88 |
89 |
91 |
93 |
94 |
95 |
1: <?php
96 | 2:
97 | 3: defined ('BASEPATH' ) OR exit ('No direct script access allowed' );
98 | 4:
99 | 5: class Rest_server extends CI_Controller {
100 | 6:
101 | 7: public function index()
102 | 8: {
103 | 9: $this ->load->helper('url' );
104 | 10:
105 | 11: $this ->load->view('rest_server' );
106 | 12: }
107 | 13: }
108 | 14:
109 |
110 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/documentation/class-Welcome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Class Welcome
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
74 |
75 |
76 |
77 |
78 | Overview
79 |
80 |
81 | Package
82 |
83 | Class
84 |
85 |
87 |
89 |
90 |
91 |
92 |
Class Welcome
93 |
94 |
95 |
96 |
97 |
98 | CI_Controller
99 |
100 |
101 |
102 |
103 |
104 | Welcome
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
126 |
127 |
128 |
129 |
130 | Methods summary
131 |
132 |
133 |
134 | public
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
#
143 |
index ( )
144 |
145 |
146 |
Index Page for this controller.
147 |
148 |
149 |
150 |
Index Page for this controller.
151 |
152 |
Maps to the following URL http://example.com/index.php/welcome
153 | - or - http://example.com/index.php/welcome/index
154 | - or -
155 | Since this controller is set as the default controller in
156 | config/routes.php, it's displayed at http://example.com/
157 |
158 |
So any other public methods not prefixed with an underscore will
159 | map to /index.php/welcome/
160 |
161 |
162 |
163 |
164 |
165 |
See
166 |
167 | https://codeigniter.com/user_guide/general/urls.html
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/application/controllers/api/Jwt.php:
--------------------------------------------------------------------------------
1 | 'password',
11 | 'user' => 'password2',
12 | 'demo' => 'password3',
13 | ];
14 |
15 | public function __construct()
16 | {
17 | parent::__construct();
18 | }
19 |
20 | //User JWT authentication to get the toekn
21 | public function token_post()
22 | {
23 | $this->load->library('form_validation');
24 |
25 | $this->form_validation->set_data([
26 | 'username' => $this->post('username'),
27 | 'password' => $this->post('password'),
28 | ]);
29 |
30 | $this->form_validation->set_rules('username', 'Username', 'required');
31 | $this->form_validation->set_rules('password', 'Password', 'required');
32 |
33 | if ($this->form_validation->run() == TRUE)
34 | {
35 | if ($this->login($this->post('username'), $this->post('password')))
36 | {
37 | $token['username'] = $this->post('username');
38 | $date = new DateTime();
39 | $token['iat'] = $date->getTimestamp();
40 | $token['exp'] = $date->getTimestamp() + $this->config->item('jwt_token_expire');
41 | $output_data['token'] = $this->jwt_encode($token);
42 | $this->response($output_data, REST_Controller::HTTP_OK);
43 | }
44 | else
45 | {
46 | $output_data[$this->config->item('rest_status_field_name')] = "invalid_credentials";
47 | $output_data[$this->config->item('rest_message_field_name')] = "Invalid username or password!";
48 | $this->response($output_data, REST_Controller::HTTP_UNAUTHORIZED);
49 | }
50 | }
51 | else
52 | {
53 | $output_data[$this->config->item('rest_status_field_name')] = "empty_fields";
54 | $output_data[$this->config->item('rest_message_field_name')] = $this->form_validation->error_array();
55 |
56 | $this->response($output_data, REST_Controller::HTTP_UNPROCESSABLE_ENTITY);
57 | }
58 | }
59 |
60 | // Refresh the token with new expirey time
61 | public function token_refresh_get()
62 | {
63 | try
64 | {
65 | $decoded = $this->jwt_decode($this->jwt_token());
66 |
67 | if($this->username_check($decoded['username']) == FALSE)
68 | {
69 | $output_data[$this->config->item('rest_status_field_name')] = "invalid_user";
70 | $output_data[$this->config->item('rest_message_field_name')] = "The token user id is not exist in the system!";
71 | $this->response($output_data, REST_Controller::HTTP_UNAUTHORIZED);
72 | }
73 |
74 | $token['username'] = $decoded['username'];
75 | $date = new DateTime();
76 | $token['iat'] = $date->getTimestamp();
77 | $token['exp'] = $date->getTimestamp() + $this->config->item('jwt_token_expire');
78 | $output_data['token'] = $this->jwt_encode($token);
79 | $this->response($output_data, REST_Controller::HTTP_OK);
80 | }
81 | catch (Exception $e)
82 | {
83 | $output_data[$this->config->item('rest_status_field_name')] = "invalid_token";
84 | $output_data[$this->config->item('rest_message_field_name')] = $e->getMessage();
85 | $this->response($output_data, REST_Controller::HTTP_UNAUTHORIZED);
86 | }
87 | }
88 |
89 | // JWT test endpoint, it shows the token information (need token authorization)
90 | public function token_info_get()
91 | {
92 | try
93 | {
94 | $output_data = $this->jwt_decode($this->jwt_token());
95 | $this->response($output_data, REST_Controller::HTTP_OK);
96 | }
97 | catch (Exception $e)
98 | {
99 | $output_data[$this->config->item('rest_status_field_name')] = "invalid_token";
100 | $output_data[$this->config->item('rest_message_field_name')] = $e->getMessage();
101 | $this->response($output_data, REST_Controller::HTTP_UNAUTHORIZED);
102 | }
103 | }
104 |
105 | // Login model emulation, login funcation
106 | private function login($username, $password)
107 | {
108 | if(array_key_exists($username, $this->accounts) AND $this->accounts[$username] === $password)
109 | {
110 | return TRUE;
111 | }
112 | return FALSE;
113 | }
114 |
115 | // Login model emulation, check if user exist on database
116 | private function username_check($username)
117 | {
118 | if(array_key_exists($username, $this->accounts))
119 | {
120 | return TRUE;
121 | }
122 | return FALSE;
123 | }
124 |
125 | }
--------------------------------------------------------------------------------
/application/controllers/api/Example.php:
--------------------------------------------------------------------------------
1 | methods['users_get']['limit'] = 500; // 500 requests per hour per user/key
30 | $this->methods['users_post']['limit'] = 100; // 100 requests per hour per user/key
31 | $this->methods['users_delete']['limit'] = 50; // 50 requests per hour per user/key
32 | }
33 |
34 | public function users_get()
35 | {
36 | // Users from a data store e.g. database
37 | $users = [
38 | ['id' => 1, 'name' => 'John', 'email' => 'john@example.com', 'fact' => 'Loves coding'],
39 | ['id' => 2, 'name' => 'Jim', 'email' => 'jim@example.com', 'fact' => 'Developed on CodeIgniter'],
40 | ['id' => 3, 'name' => 'Jane', 'email' => 'jane@example.com', 'fact' => 'Lives in the USA', ['hobbies' => ['guitar', 'cycling']]],
41 | ];
42 |
43 | $id = $this->get('id');
44 |
45 | // If the id parameter doesn't exist return all the users
46 |
47 | if ($id === NULL)
48 | {
49 | // Check if the users data store contains users (in case the database result returns NULL)
50 | if ($users)
51 | {
52 | // Set the response and exit
53 | $this->response($users, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
54 | }
55 | else
56 | {
57 | // Set the response and exit
58 | $this->response([
59 | 'status' => FALSE,
60 | 'message' => 'No users were found'
61 | ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code
62 | }
63 | }
64 |
65 | // Find and return a single record for a particular user.
66 |
67 | $id = (int) $id;
68 |
69 | // Validate the id.
70 | if ($id <= 0)
71 | {
72 | // Invalid id, set the response and exit.
73 | $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
74 | }
75 |
76 | // Get the user from the array, using the id as key for retrieval.
77 | // Usually a model is to be used for this.
78 |
79 | $user = NULL;
80 |
81 | if (!empty($users))
82 | {
83 | foreach ($users as $key => $value)
84 | {
85 | if (isset($value['id']) && $value['id'] === $id)
86 | {
87 | $user = $value;
88 | }
89 | }
90 | }
91 |
92 | if (!empty($user))
93 | {
94 | $this->set_response($user, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
95 | }
96 | else
97 | {
98 | $this->set_response([
99 | 'status' => FALSE,
100 | 'message' => 'User could not be found'
101 | ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code
102 | }
103 | }
104 |
105 | public function users_post()
106 | {
107 | // $this->some_model->update_user( ... );
108 | $message = [
109 | 'id' => 100, // Automatically generated by the model
110 | 'name' => $this->post('name'),
111 | 'email' => $this->post('email'),
112 | 'message' => 'Added a resource'
113 | ];
114 |
115 | $this->set_response($message, REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
116 | }
117 |
118 | public function users_delete()
119 | {
120 | $id = (int) $this->get('id');
121 |
122 | // Validate the id.
123 | if ($id <= 0)
124 | {
125 | // Set the response and exit
126 | $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
127 | }
128 |
129 | // $this->some_model->delete_something($id);
130 | $message = [
131 | 'id' => $id,
132 | 'message' => 'Deleted the resource'
133 | ];
134 |
135 | $this->set_response($message, REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/documentation/source-class-Welcome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | File controllers/Welcome.php
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
78 |
79 |
80 |
81 |
82 | Overview
83 |
84 |
85 | Package
86 |
87 | Class
88 |
89 |
91 |
93 |
94 |
95 |
1: <?php
96 | 2: defined ('BASEPATH' ) OR exit ('No direct script access allowed' );
97 | 3:
98 | 4: class Welcome extends CI_Controller {
99 | 5:
100 | 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
115 | 21: public function index()
116 | 22: {
117 | 23: $this ->load->helper('url' );
118 | 24:
119 | 25: $this ->load->view('welcome_message' );
120 | 26: }
121 | 27: }
122 | 28:
123 |
124 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/application/views/rest_server.php:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 | REST Server Tests
10 |
11 |
70 |
71 |
72 |
73 |
117 |
118 |
119 |
120 |
220 |
221 |
222 |
223 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodeIgniter Rest Server with JWT Authentication
2 |
3 | [](https://gitter.im/codeigniter-restserver/Lobby)
4 |
5 | A fully RESTful server implementation for CodeIgniter using one library, one
6 | config file and one controller.
7 |
8 | ## Requirements
9 |
10 | 1. PHP 5.4 or greater
11 | 2. CodeIgniter 3.0+
12 |
13 | _Note: for 1.7.x support download v2.2 from Downloads tab_
14 |
15 | ## Important Update on 4.0.0
16 |
17 | Please note that version 4.0.0 is in the works, and is considered a breaking change (per SemVer). As CI 3.1.0 now has native support for Composer, this library will be moving to be composer based.
18 |
19 | Take a look at the "development" branch to see what's up.
20 |
21 | ## Installation
22 |
23 | Drag and drop the **application/libraries/Format.php** and **application/libraries/REST_Controller.php** files into your application's directories. To use `require_once` it at the top of your controllers to load it into the scope. Additionally, copy the **rest.php** file from **application/config** in your application's configuration directory.
24 |
25 | ## Handling Requests
26 |
27 | When your controller extends from `REST_Controller`, the method names will be appended with the HTTP method used to access the request. If you're making an HTTP `GET` call to `/books`, for instance, it would call a `Books#index_get()` method.
28 |
29 | This allows you to implement a RESTful interface easily:
30 |
31 | ```php
32 | class Books extends REST_Controller
33 | {
34 | public function index_get()
35 | {
36 | // Display all books
37 | }
38 |
39 | public function index_post()
40 | {
41 | // Create a new book
42 | }
43 | }
44 | ```
45 |
46 | `REST_Controller` also supports `PUT` and `DELETE` methods, allowing you to support a truly RESTful interface.
47 |
48 |
49 | Accessing parameters is also easy. Simply use the name of the HTTP verb as a method:
50 |
51 | ```php
52 | $this->get('blah'); // GET param
53 | $this->post('blah'); // POST param
54 | $this->put('blah'); // PUT param
55 | ```
56 |
57 | The HTTP spec for DELETE requests precludes the use of parameters. For delete requests, you can add items to the URL
58 |
59 | ```php
60 | public function index_delete($id)
61 | {
62 | $this->response([
63 | 'returned from delete:' => $id,
64 | ]);
65 | }
66 | ```
67 |
68 | If query parameters are passed via the URL, regardless of whether it's a GET request, can be obtained by the query method:
69 |
70 | ```php
71 | $this->query('blah'); // Query param
72 | ```
73 |
74 | ## Content Types
75 |
76 | `REST_Controller` supports a bunch of different request/response formats, including XML, JSON and serialised PHP. By default, the class will check the URL and look for a format either as an extension or as a separate segment.
77 |
78 | This means your URLs can look like this:
79 | ```
80 | http://example.com/books.json
81 | http://example.com/books?format=json
82 | ```
83 |
84 | This can be flaky with URI segments, so the recommend approach is using the HTTP `Accept` header:
85 |
86 | ```bash
87 | $ curl -H "Accept: application/json" http://example.com
88 | ```
89 |
90 | Any responses you make from the class (see [responses](#responses) for more on this) will be serialised in the designated format.
91 |
92 | ## Responses
93 |
94 | The class provides a `response()` method that allows you to return data in the user's requested response format.
95 |
96 | Returning any object / array / string / whatever is easy:
97 |
98 | ```php
99 | public function index_get()
100 | {
101 | $this->response($this->db->get('books')->result());
102 | }
103 | ```
104 |
105 | This will automatically return an `HTTP 200 OK` response. You can specify the status code in the second parameter:
106 |
107 | ```php
108 | public function index_post()
109 | {
110 | // ...create new book
111 | $this->response($book, 201); // Send an HTTP 201 Created
112 | }
113 | ```
114 |
115 | If you don't specify a response code, and the data you respond with `== FALSE` (an empty array or string, for instance), the response code will automatically be set to `404 Not Found`:
116 |
117 | ```php
118 | $this->response([]); // HTTP 404 Not Found
119 | ```
120 |
121 | ## Multilingual Support
122 |
123 | If your application uses language files to support multiple locales, `REST_Controller` will automatically parse the HTTP `Accept-Language` header and provide the language(s) in your actions. This information can be found in the `$this->response->lang` object:
124 |
125 | ```php
126 | public function __construct()
127 | {
128 | parent::__construct();
129 |
130 | if (is_array($this->response->lang))
131 | {
132 | $this->load->language('application', $this->response->lang[0]);
133 | }
134 | else
135 | {
136 | $this->load->language('application', $this->response->lang);
137 | }
138 | }
139 | ```
140 |
141 | ## Authentication
142 |
143 | This class also provides rudimentary support for HTTP basic authentication and/or the securer HTTP digest access authentication.
144 |
145 | You can enable basic authentication by setting the `$config['rest_auth']` to `'basic'`. The `$config['rest_valid_logins']` directive can then be used to set the usernames and passwords able to log in to your system. The class will automatically send all the correct headers to trigger the authentication dialogue:
146 |
147 | ```php
148 | $config['rest_valid_logins'] = ['username' => 'password', 'other_person' => 'secure123'];
149 | ```
150 |
151 | Enabling digest auth is similarly easy. Configure your desired logins in the config file like above, and set `$config['rest_auth']` to `'digest'`. The class will automatically send out the headers to enable digest auth.
152 |
153 | If you're tying this library into an AJAX endpoint where clients authenticate using PHP sessions then you may not like either of the digest nor basic authentication methods. In that case, you can tell the REST Library what PHP session variable to check for. If the variable exists, then the user is authorized. It will be up to your application to set that variable. You can define the variable in ``$config['auth_source']``. Then tell the library to use a php session variable by setting ``$config['rest_auth']`` to ``session``.
154 |
155 | All three methods of authentication can be secured further by using an IP white-list. If you enable `$config['rest_ip_whitelist_enabled']` in your config file, you can then set a list of allowed IPs.
156 |
157 | Any client connecting to your API will be checked against the white-listed IP array. If they're on the list, they'll be allowed access. If not, sorry, no can do hombre. The whitelist is a comma-separated string:
158 |
159 | ```php
160 | $config['rest_ip_whitelist'] = '123.456.789.0, 987.654.32.1';
161 | ```
162 |
163 | Your localhost IPs (`127.0.0.1` and `0.0.0.0`) are allowed by default.
164 |
165 | ## API Keys
166 |
167 | In addition to the authentication methods above, the `REST_Controller` class also supports the use of API keys. Enabling API keys is easy. Turn it on in your **config/rest.php** file:
168 |
169 | ```php
170 | $config['rest_enable_keys'] = TRUE;
171 | ```
172 |
173 | You'll need to create a new database table to store and access the keys. `REST_Controller` will automatically assume you have a table that looks like this:
174 |
175 | ```sql
176 | CREATE TABLE `keys` (
177 | `id` INT(11) NOT NULL AUTO_INCREMENT,
178 | `key` VARCHAR(40) NOT NULL,
179 | `level` INT(2) NOT NULL,
180 | `ignore_limits` TINYINT(1) NOT NULL DEFAULT '0',
181 | `date_created` INT(11) NOT NULL,
182 | PRIMARY KEY (`id`)
183 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
184 | ```
185 |
186 | The class will look for an HTTP header with the API key on each request. An invalid or missing API key will result in an `HTTP 403 Forbidden`.
187 |
188 | By default, the HTTP will be `X-API-KEY`. This can be configured in **config/rest.php**.
189 |
190 | ```bash
191 | $ curl -X POST -H "X-API-KEY: some_key_here" http://example.com/books
192 | ```
193 |
194 | ## Other Documentation / Tutorials
195 |
196 | * [NetTuts: Working with RESTful Services in CodeIgniter](http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/)
197 |
198 | ## Contributions
199 |
200 | This project was originally written by Phil Sturgeon, however his involvement has shifted
201 | as he is no longer using it. As of 2013/11/20 further development and support will be done by Chris Kacerguis.
202 |
203 | Pull Requests are the best way to fix bugs or add features. I know loads of you use this, so please
204 | contribute if you have improvements to be made and I'll keep releasing versions over time.
205 |
206 | [](https://raw.githubusercontent.com/chriskacerguis/codeigniter-restserver/master/LICENSE)
207 |
--------------------------------------------------------------------------------
/application/controllers/api/Key.php:
--------------------------------------------------------------------------------
1 | ['level' => 10, 'limit' => 10],
24 | 'index_delete' => ['level' => 10],
25 | 'level_post' => ['level' => 10],
26 | 'regenerate_post' => ['level' => 10],
27 | ];
28 |
29 | /**
30 | * Insert a key into the database
31 | *
32 | * @access public
33 | * @return void
34 | */
35 | public function index_put()
36 | {
37 | // Build a new key
38 | $key = $this->_generate_key();
39 |
40 | // If no key level provided, provide a generic key
41 | $level = $this->put('level') ? $this->put('level') : 1;
42 | $ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1;
43 |
44 | // Insert the new key
45 | if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits]))
46 | {
47 | $this->response([
48 | 'status' => TRUE,
49 | 'key' => $key
50 | ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
51 | }
52 | else
53 | {
54 | $this->response([
55 | 'status' => FALSE,
56 | 'message' => 'Could not save the key'
57 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
58 | }
59 | }
60 |
61 | /**
62 | * Remove a key from the database to stop it working
63 | *
64 | * @access public
65 | * @return void
66 | */
67 | public function index_delete()
68 | {
69 | $key = $this->delete('key');
70 |
71 | // Does this key exist?
72 | if (!$this->_key_exists($key))
73 | {
74 | // It doesn't appear the key exists
75 | $this->response([
76 | 'status' => FALSE,
77 | 'message' => 'Invalid API key'
78 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
79 | }
80 |
81 | // Destroy it
82 | $this->_delete_key($key);
83 |
84 | // Respond that the key was destroyed
85 | $this->response([
86 | 'status' => TRUE,
87 | 'message' => 'API key was deleted'
88 | ], REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code
89 | }
90 |
91 | /**
92 | * Change the level
93 | *
94 | * @access public
95 | * @return void
96 | */
97 | public function level_post()
98 | {
99 | $key = $this->post('key');
100 | $new_level = $this->post('level');
101 |
102 | // Does this key exist?
103 | if (!$this->_key_exists($key))
104 | {
105 | // It doesn't appear the key exists
106 | $this->response([
107 | 'status' => FALSE,
108 | 'message' => 'Invalid API key'
109 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
110 | }
111 |
112 | // Update the key level
113 | if ($this->_update_key($key, ['level' => $new_level]))
114 | {
115 | $this->response([
116 | 'status' => TRUE,
117 | 'message' => 'API key was updated'
118 | ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
119 | }
120 | else
121 | {
122 | $this->response([
123 | 'status' => FALSE,
124 | 'message' => 'Could not update the key level'
125 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
126 | }
127 | }
128 |
129 | /**
130 | * Suspend a key
131 | *
132 | * @access public
133 | * @return void
134 | */
135 | public function suspend_post()
136 | {
137 | $key = $this->post('key');
138 |
139 | // Does this key exist?
140 | if (!$this->_key_exists($key))
141 | {
142 | // It doesn't appear the key exists
143 | $this->response([
144 | 'status' => FALSE,
145 | 'message' => 'Invalid API key'
146 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
147 | }
148 |
149 | // Update the key level
150 | if ($this->_update_key($key, ['level' => 0]))
151 | {
152 | $this->response([
153 | 'status' => TRUE,
154 | 'message' => 'Key was suspended'
155 | ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
156 | }
157 | else
158 | {
159 | $this->response([
160 | 'status' => FALSE,
161 | 'message' => 'Could not suspend the user'
162 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
163 | }
164 | }
165 |
166 | /**
167 | * Regenerate a key
168 | *
169 | * @access public
170 | * @return void
171 | */
172 | public function regenerate_post()
173 | {
174 | $old_key = $this->post('key');
175 | $key_details = $this->_get_key($old_key);
176 |
177 | // Does this key exist?
178 | if (!$key_details)
179 | {
180 | // It doesn't appear the key exists
181 | $this->response([
182 | 'status' => FALSE,
183 | 'message' => 'Invalid API key'
184 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
185 | }
186 |
187 | // Build a new key
188 | $new_key = $this->_generate_key();
189 |
190 | // Insert the new key
191 | if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits]))
192 | {
193 | // Suspend old key
194 | $this->_update_key($old_key, ['level' => 0]);
195 |
196 | $this->response([
197 | 'status' => TRUE,
198 | 'key' => $new_key
199 | ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
200 | }
201 | else
202 | {
203 | $this->response([
204 | 'status' => FALSE,
205 | 'message' => 'Could not save the key'
206 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
207 | }
208 | }
209 |
210 | /* Helper Methods */
211 |
212 | private function _generate_key()
213 | {
214 | do
215 | {
216 | // Generate a random salt
217 | $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
218 |
219 | // If an error occurred, then fall back to the previous method
220 | if ($salt === FALSE)
221 | {
222 | $salt = hash('sha256', time() . mt_rand());
223 | }
224 |
225 | $new_key = substr($salt, 0, config_item('rest_key_length'));
226 | }
227 | while ($this->_key_exists($new_key));
228 |
229 | return $new_key;
230 | }
231 |
232 | /* Private Data Methods */
233 |
234 | private function _get_key($key)
235 | {
236 | return $this->rest->db
237 | ->where(config_item('rest_key_column'), $key)
238 | ->get(config_item('rest_keys_table'))
239 | ->row();
240 | }
241 |
242 | private function _key_exists($key)
243 | {
244 | return $this->rest->db
245 | ->where(config_item('rest_key_column'), $key)
246 | ->count_all_results(config_item('rest_keys_table')) > 0;
247 | }
248 |
249 | private function _insert_key($key, $data)
250 | {
251 | $data[config_item('rest_key_column')] = $key;
252 | $data['date_created'] = function_exists('now') ? now() : time();
253 |
254 | return $this->rest->db
255 | ->set($data)
256 | ->insert(config_item('rest_keys_table'));
257 | }
258 |
259 | private function _update_key($key, $data)
260 | {
261 | return $this->rest->db
262 | ->where(config_item('rest_key_column'), $key)
263 | ->update(config_item('rest_keys_table'), $data);
264 | }
265 |
266 | private function _delete_key($key)
267 | {
268 | return $this->rest->db
269 | ->where(config_item('rest_key_column'), $key)
270 | ->delete(config_item('rest_keys_table'));
271 | }
272 |
273 | }
274 |
--------------------------------------------------------------------------------
/documentation/resources/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | font: 13px/1.5 Verdana, 'Geneva CE', lucida, sans-serif;
3 | margin: 0;
4 | padding: 0;
5 | background: #ffffff;
6 | color: #333333;
7 | }
8 |
9 | h1, h2, h3, h4, caption {
10 | font-family: 'Trebuchet MS', 'Geneva CE', lucida, sans-serif;
11 | color: #053368;
12 | }
13 |
14 | h1 {
15 | color: #1e5eb6;
16 | font-size: 230%;
17 | font-weight: normal;
18 | margin: .3em 0;
19 | }
20 |
21 | h2 {
22 | color: #1e5eb6;
23 | font-size: 150%;
24 | font-weight: normal;
25 | margin: -.3em 0 .3em 0;
26 | }
27 |
28 | h3 {
29 | font-size: 1.6em;
30 | font-weight: normal;
31 | margin-bottom: 2px;
32 | }
33 |
34 | h4 {
35 | font-size: 100%;
36 | font-weight: bold;
37 | padding: 0;
38 | margin: 0;
39 | }
40 |
41 | caption {
42 | border: 1px solid #cccccc;
43 | background: #ecede5;
44 | font-weight: bold;
45 | font-size: 1.2em;
46 | padding: 3px 5px;
47 | text-align: left;
48 | margin-bottom: 0;
49 | }
50 |
51 | p {
52 | margin: .7em 0 1em;
53 | padding: 0;
54 | }
55 |
56 | hr {
57 | margin: 2em 0 1em;
58 | border: none;
59 | border-top: 1px solid #cccccc;
60 | height: 0;
61 | }
62 |
63 | a {
64 | color: #006aeb;
65 | padding: 3px 1px;
66 | text-decoration: none;
67 | }
68 |
69 | h1 a {
70 | color: #1e5eb6;
71 | }
72 |
73 | a:hover, a:active, a:focus, a:hover b, a:hover var {
74 | background-color: #006aeb;
75 | color: #ffffff !important;
76 | }
77 |
78 | code, var, pre {
79 | font-family: monospace;
80 | }
81 |
82 | var {
83 | font-weight: bold;
84 | font-style: normal;
85 | color: #ca8a04;
86 | }
87 |
88 | pre {
89 | margin: 0;
90 | }
91 |
92 | code a b {
93 | color: #000000;
94 | }
95 |
96 | .deprecated {
97 | text-decoration: line-through;
98 | opacity: .5;
99 | }
100 |
101 | .invalid {
102 | color: #e71818;
103 | }
104 |
105 | .hidden {
106 | display: none;
107 | }
108 |
109 | /* Left side */
110 | #left {
111 | overflow: auto;
112 | width: 270px;
113 | height: 100%;
114 | position: fixed;
115 | }
116 |
117 | /* Menu */
118 | #menu {
119 | padding: 10px;
120 | }
121 |
122 | #menu ul {
123 | list-style: none;
124 | padding: 0;
125 | margin: 0;
126 | }
127 |
128 | #menu ul ul {
129 | padding-left: 10px;
130 | }
131 |
132 | #menu li {
133 | white-space: nowrap;
134 | position: relative;
135 | }
136 |
137 | #menu a {
138 | display: block;
139 | padding: 0 2px;
140 | }
141 |
142 | #menu .active > a, #menu > span {
143 | color: #333333;
144 | background: none;
145 | font-weight: bold;
146 | }
147 |
148 | #menu .active > a.invalid {
149 | color: #e71818;
150 | }
151 |
152 | #menu .active > a:hover, #menu .active > a:active, #menu .active > a:focus {
153 | background-color: #006aeb;
154 | }
155 |
156 | #menu #groups span {
157 | position: absolute;
158 | top: 4px;
159 | right: 2px;
160 | cursor: pointer;
161 | display: block;
162 | width: 12px;
163 | height: 12px;
164 | background: url('collapsed.png') transparent 0 0 no-repeat;
165 | }
166 |
167 | #menu #groups span:hover {
168 | background-position: -12px 0;
169 | }
170 |
171 | #menu #groups span.collapsed {
172 | background-position: 0 -12px;
173 | }
174 |
175 | #menu #groups span.collapsed:hover {
176 | background-position: -12px -12px;
177 | }
178 |
179 | #menu #groups ul.collapsed {
180 | display: none;
181 | }
182 |
183 | /* Right side */
184 | #right {
185 | overflow: auto;
186 | margin-left: 275px;
187 | height: 100%;
188 | position: relative;
189 | left: 0;
190 | right: 0;
191 | }
192 |
193 | #rightInner {
194 | max-width: 1000px;
195 | min-width: 350px;
196 | }
197 |
198 | /* Search */
199 | #search {
200 | float: right;
201 | margin: 3px 8px;
202 | }
203 |
204 | #search input.text {
205 | padding: 3px 5px;
206 | width: 250px;
207 | }
208 |
209 | /* Autocomplete */
210 | .ac_results {
211 | padding: 0;
212 | border: 1px solid #cccccc;
213 | background-color: #ffffff;
214 | overflow: hidden;
215 | z-index: 99999;
216 | }
217 |
218 | .ac_results ul {
219 | width: 100%;
220 | list-style-position: outside;
221 | list-style: none;
222 | padding: 0;
223 | margin: 0;
224 | }
225 |
226 | .ac_results li {
227 | margin: 0;
228 | padding: 2px 5px;
229 | cursor: default;
230 | display: block;
231 | font: 12px 'Trebuchet MS', 'Geneva CE', lucida, sans-serif;
232 | line-height: 16px;
233 | overflow: hidden;
234 | white-space: nowrap;
235 | }
236 |
237 | .ac_results li strong {
238 | color: #000000;
239 | }
240 |
241 | .ac_odd {
242 | background-color: #eeeeee;
243 | }
244 |
245 | .ac_over {
246 | background-color: #006aeb;
247 | color: #ffffff;
248 | }
249 |
250 | .ac_results li.ac_over strong {
251 | color: #ffffff;
252 | }
253 |
254 | /* Navigation */
255 | #navigation {
256 | padding: 3px 8px;
257 | background-color: #f6f6f4;
258 | height: 26px;
259 | }
260 |
261 | #navigation ul {
262 | list-style: none;
263 | margin: 0 8px 4px 0;
264 | padding: 0;
265 | overflow: hidden;
266 | float: left;
267 | }
268 |
269 | #navigation ul + ul {
270 | border-left: 1px solid #000000;
271 | padding-left: 8px;
272 | }
273 |
274 | #navigation ul li {
275 | float: left;
276 | margin: 2px;
277 | padding: 0 3px;
278 | font-family: Verdana, 'Geneva CE', lucida, sans-serif;
279 | color: #808080;
280 | }
281 |
282 | #navigation ul li.active {
283 | background-color: #053368;
284 | color: #ffffff;
285 | font-weight: bold;
286 | }
287 |
288 | #navigation ul li a {
289 | color: #000000;
290 | font-weight: bold;
291 | padding: 0;
292 | }
293 |
294 | #navigation ul li span {
295 | float: left;
296 | padding: 0 3px;
297 | }
298 |
299 | #navigation ul li a:hover span, #navigation ul li a:active span, #navigation ul li a:focus span {
300 | background-color: #006aeb;
301 | }
302 |
303 | /* Content */
304 | #content {
305 | clear: both;
306 | padding: 5px 15px;
307 | }
308 |
309 | .description pre {
310 | padding: .6em;
311 | background: #fcfcf7;
312 | }
313 |
314 | #content > .description {
315 | background: #ecede5;
316 | padding: 1px 8px;
317 | margin: 1.2em 0;
318 | }
319 |
320 | #content > .description pre {
321 | margin: .5em 0;
322 | }
323 |
324 | dl.tree {
325 | margin: 1.2em 0;
326 | }
327 |
328 | dl.tree dd {
329 | margin: 0;
330 | padding: 0;
331 | }
332 |
333 | .info {
334 | margin: 1.2em 0;
335 | }
336 |
337 | .summary {
338 | border: 1px solid #cccccc;
339 | border-collapse: collapse;
340 | font-size: 1em;
341 | width: 100%;
342 | margin: 1.2em 0 2.4em;
343 | }
344 |
345 | .summary caption {
346 | border-width: 1px 1px 0;
347 | }
348 |
349 | .summary caption.switchable {
350 | background: #ecede5 url('sort.png') no-repeat center right;
351 | cursor: pointer;
352 | }
353 |
354 | .summary td {
355 | border: 1px solid #cccccc;
356 | margin: 0;
357 | padding: 3px 10px;
358 | font-size: 1em;
359 | vertical-align: top;
360 | }
361 |
362 | .summary td:first-child {
363 | text-align: right;
364 | }
365 |
366 | .summary td hr {
367 | margin: 3px -10px;
368 | }
369 |
370 | #packages.summary td:first-child, #namespaces.summary td:first-child, .inherited.summary td:first-child, .used.summary td:first-child {
371 | text-align: left;
372 | }
373 |
374 | .summary tr:hover td {
375 | background: #f6f6f4;
376 | }
377 |
378 | .summary .description pre {
379 | border: .5em solid #ecede5;
380 | }
381 |
382 | .summary .description p {
383 | margin: 0;
384 | }
385 |
386 | .summary .description p + p, .summary .description ul {
387 | margin: 3px 0 0 0;
388 | }
389 |
390 | .summary .description.detailed h4 {
391 | margin-top: 3px;
392 | }
393 |
394 | .summary dl {
395 | margin: 0;
396 | }
397 |
398 | .summary dd {
399 | margin: 0 0 0 25px;
400 | }
401 |
402 | .name, .attributes {
403 | white-space: nowrap;
404 | }
405 |
406 | .value code {
407 | white-space: pre-wrap;
408 | }
409 |
410 | td.name, td.attributes {
411 | width: 1%;
412 | }
413 |
414 | td.attributes {
415 | width: 1%;
416 | }
417 |
418 | .class .methods .name, .class .properties .name, .class .constants .name {
419 | width: auto;
420 | white-space: normal;
421 | }
422 |
423 | .class .methods .name > div > code {
424 | white-space: pre-wrap;
425 | }
426 |
427 | .class .methods .name > div > code span, .function .value > code {
428 | white-space: nowrap;
429 | }
430 |
431 | .class .methods td.name > div, .class td.value > div {
432 | position: relative;
433 | padding-right: 1em;
434 | }
435 |
436 | .anchor {
437 | position: absolute;
438 | top: 0;
439 | right: 0;
440 | line-height: 1;
441 | font-size: 85%;
442 | margin: 0;
443 | color: #006aeb !important;
444 | }
445 |
446 | .list {
447 | margin: 0 0 5px 25px;
448 | }
449 |
450 | div.invalid {
451 | background-color: #fae4e0;
452 | padding: 10px;
453 | }
454 |
455 | /* Splitter */
456 | #splitter {
457 | position: fixed;
458 | height: 100%;
459 | width: 5px;
460 | left: 270px;
461 | background: #1e5eb6 url('resize.png') left center no-repeat;
462 | cursor: e-resize;
463 | }
464 |
465 | #splitter.active {
466 | opacity: .5;
467 | }
468 |
469 | /* Footer */
470 | #footer {
471 | border-top: 1px solid #e9eeef;
472 | clear: both;
473 | color: #a7a7a7;
474 | font-size: 8pt;
475 | text-align: center;
476 | padding: 20px 0 0;
477 | margin: 3em 0 0;
478 | height: 90px;
479 | background: #ffffff url('footer.png') no-repeat center top;
480 | }
481 |
482 | /* Tree */
483 | div.tree ul {
484 | list-style: none;
485 | background: url('tree-vertical.png') left repeat-y;
486 | padding: 0;
487 | margin-left: 20px;
488 | }
489 |
490 | div.tree li {
491 | margin: 0;
492 | padding: 0;
493 | }
494 |
495 | div.tree div {
496 | padding-left: 30px;
497 | }
498 |
499 | div.tree div.notlast {
500 | background: url('tree-hasnext.png') left 10px no-repeat;
501 | }
502 |
503 | div.tree div.last {
504 | background: url('tree-last.png') left -240px no-repeat;
505 | }
506 |
507 | div.tree li.last {
508 | background: url('tree-cleaner.png') left center repeat-y;
509 | }
510 |
511 | div.tree span.padding {
512 | padding-left: 15px;
513 | }
514 |
515 | /* Source code */
516 | .php-keyword1 {
517 | color: #e71818;
518 | font-weight: bold;
519 | }
520 |
521 | .php-keyword2 {
522 | font-weight: bold;
523 | }
524 |
525 | .php-var {
526 | color: #d59401;
527 | font-weight: bold;
528 | }
529 |
530 | .php-num {
531 | color: #cd0673;
532 | }
533 |
534 | .php-quote {
535 | color: #008000;
536 | }
537 |
538 | .php-comment {
539 | color: #929292;
540 | }
541 |
542 | .xlang {
543 | color: #ff0000;
544 | font-weight: bold;
545 | }
546 |
547 | span.l {
548 | display: block;
549 | }
550 |
551 | span.l.selected {
552 | background: #f6f6f4;
553 | }
554 |
555 | span.l a {
556 | color: #333333;
557 | }
558 |
559 | span.l a:hover, div.l a:active, div.l a:focus {
560 | background: transparent;
561 | color: #333333 !important;
562 | }
563 |
564 | span.l .php-var a {
565 | color: #d59401;
566 | }
567 |
568 | span.l .php-var a:hover, span.l .php-var a:active, span.l .php-var a:focus {
569 | color: #d59401 !important;
570 | }
571 |
572 | span.l a.l {
573 | padding-left: 2px;
574 | color: #c0c0c0;
575 | }
576 |
577 | span.l a.l:hover, span.l a.l:active, span.l a.l:focus {
578 | background: transparent;
579 | color: #c0c0c0 !important;
580 | }
581 |
582 | #rightInner.medium #navigation {
583 | height: 52px;
584 | }
585 |
586 | #rightInner.medium #navigation ul:first-child + ul {
587 | clear: left;
588 | border: none;
589 | padding: 0;
590 | }
591 |
592 | #rightInner.medium .name, #rightInner.medium .attributes {
593 | white-space: normal;
594 | }
595 |
596 | #rightInner.small #search {
597 | float: left;
598 | }
599 |
600 | #rightInner.small #navigation {
601 | height: 78px;
602 | }
603 |
604 | #rightInner.small #navigation ul:first-child {
605 | clear: both;
606 | }
607 |
608 | /* global style */
609 | .left, .summary td.left {
610 | text-align: left;
611 | }
612 | .right, .summary td.right {
613 | text-align: right;
614 | }
615 |
--------------------------------------------------------------------------------
/application/libraries/jwt/JWT.php:
--------------------------------------------------------------------------------
1 |
18 | * @author Anant Narayanan
19 | * @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
20 | * @link https://github.com/firebase/php-jwt
21 | */
22 | class JWT
23 | {
24 |
25 | /**
26 | * When checking nbf, iat or expiration times,
27 | * we want to provide some extra leeway time to
28 | * account for clock skew.
29 | */
30 | public static $leeway = 0;
31 |
32 | /**
33 | * Allow the current timestamp to be specified.
34 | * Useful for fixing a value within unit testing.
35 | *
36 | * Will default to PHP time() value if null.
37 | */
38 | public static $timestamp = null;
39 |
40 | public static $supported_algs = array(
41 | 'HS256' => array('hash_hmac', 'SHA256'),
42 | 'HS512' => array('hash_hmac', 'SHA512'),
43 | 'HS384' => array('hash_hmac', 'SHA384'),
44 | 'RS256' => array('openssl', 'SHA256'),
45 | );
46 |
47 | /**
48 | * Decodes a JWT string into a PHP object.
49 | *
50 | * @param string $jwt The JWT
51 | * @param string|array $key The key, or map of keys.
52 | * If the algorithm used is asymmetric, this is the public key
53 | * @param array $allowed_algs List of supported verification algorithms
54 | * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
55 | *
56 | * @return object The JWT's payload as a PHP object
57 | *
58 | * @throws UnexpectedValueException Provided JWT was invalid
59 | * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed
60 | * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf'
61 | * @throws BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat'
62 | * @throws ExpiredException Provided JWT has since expired, as defined by the 'exp' claim
63 | *
64 | * @uses jsonDecode
65 | * @uses urlsafeB64Decode
66 | */
67 | public static function decode($jwt, $key, $allowed_algs = array())
68 | {
69 | $timestamp = is_null(static::$timestamp) ? time() : static::$timestamp;
70 |
71 | if (empty($key)) {
72 | throw new InvalidArgumentException('Key may not be empty');
73 | }
74 | if (!is_array($allowed_algs)) {
75 | throw new InvalidArgumentException('Algorithm not allowed');
76 | }
77 | $tks = explode('.', $jwt);
78 | if (count($tks) != 3) {
79 | throw new UnexpectedValueException('Wrong number of segments');
80 | }
81 | list($headb64, $bodyb64, $cryptob64) = $tks;
82 | if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
83 | throw new UnexpectedValueException('Invalid header encoding');
84 | }
85 | if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
86 | throw new UnexpectedValueException('Invalid claims encoding');
87 | }
88 | $sig = static::urlsafeB64Decode($cryptob64);
89 |
90 | if (empty($header->alg)) {
91 | throw new UnexpectedValueException('Empty algorithm');
92 | }
93 | if (empty(static::$supported_algs[$header->alg])) {
94 | throw new UnexpectedValueException('Algorithm not supported');
95 | }
96 | if (!in_array($header->alg, $allowed_algs)) {
97 | throw new UnexpectedValueException('Algorithm not allowed');
98 | }
99 | if (is_array($key) || $key instanceof \ArrayAccess) {
100 | if (isset($header->kid)) {
101 | $key = $key[$header->kid];
102 | } else {
103 | throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
104 | }
105 | }
106 |
107 | // Check the signature
108 | if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
109 | throw new SignatureInvalidException('Signature verification failed');
110 | }
111 |
112 | // Check if the nbf if it is defined. This is the time that the
113 | // token can actually be used. If it's not yet that time, abort.
114 | if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
115 | throw new BeforeValidException(
116 | 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
117 | );
118 | }
119 |
120 | // Check that this token has been created before 'now'. This prevents
121 | // using tokens that have been created for later use (and haven't
122 | // correctly used the nbf claim).
123 | if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
124 | throw new BeforeValidException(
125 | 'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
126 | );
127 | }
128 |
129 | // Check if this token has expired.
130 | if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
131 | throw new ExpiredException('Expired token');
132 | }
133 |
134 | return $payload;
135 | }
136 |
137 | /**
138 | * Converts and signs a PHP object or array into a JWT string.
139 | *
140 | * @param object|array $payload PHP object or array
141 | * @param string $key The secret key.
142 | * If the algorithm used is asymmetric, this is the private key
143 | * @param string $alg The signing algorithm.
144 | * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
145 | * @param mixed $keyId
146 | * @param array $head An array with header elements to attach
147 | *
148 | * @return string A signed JWT
149 | *
150 | * @uses jsonEncode
151 | * @uses urlsafeB64Encode
152 | */
153 | public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
154 | {
155 | $header = array('typ' => 'JWT', 'alg' => $alg);
156 | if ($keyId !== null) {
157 | $header['kid'] = $keyId;
158 | }
159 | if ( isset($head) && is_array($head) ) {
160 | $header = array_merge($head, $header);
161 | }
162 | $segments = array();
163 | $segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
164 | $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
165 | $signing_input = implode('.', $segments);
166 |
167 | $signature = static::sign($signing_input, $key, $alg);
168 | $segments[] = static::urlsafeB64Encode($signature);
169 |
170 | return implode('.', $segments);
171 | }
172 |
173 | /**
174 | * Sign a string with a given key and algorithm.
175 | *
176 | * @param string $msg The message to sign
177 | * @param string|resource $key The secret key
178 | * @param string $alg The signing algorithm.
179 | * Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
180 | *
181 | * @return string An encrypted message
182 | *
183 | * @throws DomainException Unsupported algorithm was specified
184 | */
185 | public static function sign($msg, $key, $alg = 'HS256')
186 | {
187 | if (empty(static::$supported_algs[$alg])) {
188 | throw new DomainException('Algorithm not supported');
189 | }
190 | list($function, $algorithm) = static::$supported_algs[$alg];
191 | switch($function) {
192 | case 'hash_hmac':
193 | return hash_hmac($algorithm, $msg, $key, true);
194 | case 'openssl':
195 | $signature = '';
196 | $success = openssl_sign($msg, $signature, $key, $algorithm);
197 | if (!$success) {
198 | throw new DomainException("OpenSSL unable to sign data");
199 | } else {
200 | return $signature;
201 | }
202 | }
203 | }
204 |
205 | /**
206 | * Verify a signature with the message, key and method. Not all methods
207 | * are symmetric, so we must have a separate verify and sign method.
208 | *
209 | * @param string $msg The original message (header and body)
210 | * @param string $signature The original signature
211 | * @param string|resource $key For HS*, a string key works. for RS*, must be a resource of an openssl public key
212 | * @param string $alg The algorithm
213 | *
214 | * @return bool
215 | *
216 | * @throws DomainException Invalid Algorithm or OpenSSL failure
217 | */
218 | private static function verify($msg, $signature, $key, $alg)
219 | {
220 | if (empty(static::$supported_algs[$alg])) {
221 | throw new DomainException('Algorithm not supported');
222 | }
223 |
224 | list($function, $algorithm) = static::$supported_algs[$alg];
225 | switch($function) {
226 | case 'openssl':
227 | $success = openssl_verify($msg, $signature, $key, $algorithm);
228 | if (!$success) {
229 | throw new DomainException("OpenSSL unable to verify data: " . openssl_error_string());
230 | } else {
231 | return $signature;
232 | }
233 | case 'hash_hmac':
234 | default:
235 | $hash = hash_hmac($algorithm, $msg, $key, true);
236 | if (function_exists('hash_equals')) {
237 | return hash_equals($signature, $hash);
238 | }
239 | $len = min(static::safeStrlen($signature), static::safeStrlen($hash));
240 |
241 | $status = 0;
242 | for ($i = 0; $i < $len; $i++) {
243 | $status |= (ord($signature[$i]) ^ ord($hash[$i]));
244 | }
245 | $status |= (static::safeStrlen($signature) ^ static::safeStrlen($hash));
246 |
247 | return ($status === 0);
248 | }
249 | }
250 |
251 | /**
252 | * Decode a JSON string into a PHP object.
253 | *
254 | * @param string $input JSON string
255 | *
256 | * @return object Object representation of JSON string
257 | *
258 | * @throws DomainException Provided string was invalid JSON
259 | */
260 | public static function jsonDecode($input)
261 | {
262 | if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
263 | /** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
264 | * to specify that large ints (like Steam Transaction IDs) should be treated as
265 | * strings, rather than the PHP default behaviour of converting them to floats.
266 | */
267 | $obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
268 | } else {
269 | /** Not all servers will support that, however, so for older versions we must
270 | * manually detect large ints in the JSON string and quote them (thus converting
271 | *them to strings) before decoding, hence the preg_replace() call.
272 | */
273 | $max_int_length = strlen((string) PHP_INT_MAX) - 1;
274 | $json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
275 | $obj = json_decode($json_without_bigints);
276 | }
277 |
278 | if (function_exists('json_last_error') && $errno = json_last_error()) {
279 | static::handleJsonError($errno);
280 | } elseif ($obj === null && $input !== 'null') {
281 | throw new DomainException('Null result with non-null input');
282 | }
283 | return $obj;
284 | }
285 |
286 | /**
287 | * Encode a PHP object into a JSON string.
288 | *
289 | * @param object|array $input A PHP object or array
290 | *
291 | * @return string JSON representation of the PHP object or array
292 | *
293 | * @throws DomainException Provided object could not be encoded to valid JSON
294 | */
295 | public static function jsonEncode($input)
296 | {
297 | $json = json_encode($input);
298 | if (function_exists('json_last_error') && $errno = json_last_error()) {
299 | static::handleJsonError($errno);
300 | } elseif ($json === 'null' && $input !== null) {
301 | throw new DomainException('Null result with non-null input');
302 | }
303 | return $json;
304 | }
305 |
306 | /**
307 | * Decode a string with URL-safe Base64.
308 | *
309 | * @param string $input A Base64 encoded string
310 | *
311 | * @return string A decoded string
312 | */
313 | public static function urlsafeB64Decode($input)
314 | {
315 | $remainder = strlen($input) % 4;
316 | if ($remainder) {
317 | $padlen = 4 - $remainder;
318 | $input .= str_repeat('=', $padlen);
319 | }
320 | return base64_decode(strtr($input, '-_', '+/'));
321 | }
322 |
323 | /**
324 | * Encode a string with URL-safe Base64.
325 | *
326 | * @param string $input The string you want encoded
327 | *
328 | * @return string The base64 encode of what you passed in
329 | */
330 | public static function urlsafeB64Encode($input)
331 | {
332 | return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
333 | }
334 |
335 | /**
336 | * Helper method to create a JSON error.
337 | *
338 | * @param int $errno An error number from json_last_error()
339 | *
340 | * @return void
341 | */
342 | private static function handleJsonError($errno)
343 | {
344 | $messages = array(
345 | JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
346 | JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
347 | JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
348 | );
349 | throw new DomainException(
350 | isset($messages[$errno])
351 | ? $messages[$errno]
352 | : 'Unknown JSON error: ' . $errno
353 | );
354 | }
355 |
356 | /**
357 | * Get the number of bytes in cryptographic strings.
358 | *
359 | * @param string
360 | *
361 | * @return int
362 | */
363 | private static function safeStrlen($str)
364 | {
365 | if (function_exists('mb_strlen')) {
366 | return mb_strlen($str, '8bit');
367 | }
368 | return strlen($str);
369 | }
370 | }
371 |
--------------------------------------------------------------------------------
/application/libraries/Format.php:
--------------------------------------------------------------------------------
1 | _CI = &get_instance();
87 |
88 | // Load the inflector helper
89 | $this->_CI->load->helper('inflector');
90 |
91 | // If the provided data is already formatted we should probably convert it to an array
92 | if ($from_type !== NULL)
93 | {
94 | if (method_exists($this, '_from_'.$from_type))
95 | {
96 | $data = call_user_func([$this, '_from_'.$from_type], $data);
97 | }
98 | else
99 | {
100 | throw new Exception('Format class does not support conversion from "'.$from_type.'".');
101 | }
102 | }
103 |
104 | // Set the member variable to the data passed
105 | $this->_data = $data;
106 | }
107 |
108 | /**
109 | * Create an instance of the format class
110 | * e.g: echo $this->format->factory(['foo' => 'bar'])->to_csv();
111 | *
112 | * @param mixed $data Data to convert/parse
113 | * @param string $from_type Type to convert from e.g. json, csv, html
114 | *
115 | * @return object Instance of the format class
116 | */
117 | public function factory($data, $from_type = NULL)
118 | {
119 | // $class = __CLASS__;
120 | // return new $class();
121 |
122 | return new static($data, $from_type);
123 | }
124 |
125 | // FORMATTING OUTPUT ---------------------------------------------------------
126 |
127 | /**
128 | * Format data as an array
129 | *
130 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed
131 | * to the constructor
132 | * @return array Data parsed as an array; otherwise, an empty array
133 | */
134 | public function to_array($data = NULL)
135 | {
136 | // If no data is passed as a parameter, then use the data passed
137 | // via the constructor
138 | if ($data === NULL && func_num_args() === 0)
139 | {
140 | $data = $this->_data;
141 | }
142 |
143 | // Cast as an array if not already
144 | if (is_array($data) === FALSE)
145 | {
146 | $data = (array) $data;
147 | }
148 |
149 | $array = [];
150 | foreach ((array) $data as $key => $value)
151 | {
152 | if (is_object($value) === TRUE || is_array($value) === TRUE)
153 | {
154 | $array[$key] = $this->to_array($value);
155 | }
156 | else
157 | {
158 | $array[$key] = $value;
159 | }
160 | }
161 |
162 | return $array;
163 | }
164 |
165 | /**
166 | * Format data as XML
167 | *
168 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed
169 | * to the constructor
170 | * @param NULL $structure
171 | * @param string $basenode
172 | * @return mixed
173 | */
174 | public function to_xml($data = NULL, $structure = NULL, $basenode = 'xml')
175 | {
176 | if ($data === NULL && func_num_args() === 0)
177 | {
178 | $data = $this->_data;
179 | }
180 |
181 | if ($structure === NULL)
182 | {
183 | $structure = simplexml_load_string("<$basenode />");
184 | }
185 |
186 | // Force it to be something useful
187 | if (is_array($data) === FALSE && is_object($data) === FALSE)
188 | {
189 | $data = (array) $data;
190 | }
191 |
192 | foreach ($data as $key => $value)
193 | {
194 |
195 | //change false/true to 0/1
196 | if (is_bool($value))
197 | {
198 | $value = (int) $value;
199 | }
200 |
201 | // no numeric keys in our xml please!
202 | if (is_numeric($key))
203 | {
204 | // make string key...
205 | $key = (singular($basenode) != $basenode) ? singular($basenode) : 'item';
206 | }
207 |
208 | // replace anything not alpha numeric
209 | $key = preg_replace('/[^a-z_\-0-9]/i', '', $key);
210 |
211 | if ($key === '_attributes' && (is_array($value) || is_object($value)))
212 | {
213 | $attributes = $value;
214 | if (is_object($attributes))
215 | {
216 | $attributes = get_object_vars($attributes);
217 | }
218 |
219 | foreach ($attributes as $attribute_name => $attribute_value)
220 | {
221 | $structure->addAttribute($attribute_name, $attribute_value);
222 | }
223 | }
224 | // if there is another array found recursively call this function
225 | elseif (is_array($value) || is_object($value))
226 | {
227 | $node = $structure->addChild($key);
228 |
229 | // recursive call.
230 | $this->to_xml($value, $node, $key);
231 | }
232 | else
233 | {
234 | // add single node.
235 | $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
236 |
237 | $structure->addChild($key, $value);
238 | }
239 | }
240 |
241 | return $structure->asXML();
242 | }
243 |
244 | /**
245 | * Format data as HTML
246 | *
247 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed
248 | * to the constructor
249 | * @return mixed
250 | */
251 | public function to_html($data = NULL)
252 | {
253 | // If no data is passed as a parameter, then use the data passed
254 | // via the constructor
255 | if ($data === NULL && func_num_args() === 0)
256 | {
257 | $data = $this->_data;
258 | }
259 |
260 | // Cast as an array if not already
261 | if (is_array($data) === FALSE)
262 | {
263 | $data = (array) $data;
264 | }
265 |
266 | // Check if it's a multi-dimensional array
267 | if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE))
268 | {
269 | // Multi-dimensional array
270 | $headings = array_keys($data[0]);
271 | }
272 | else
273 | {
274 | // Single array
275 | $headings = array_keys($data);
276 | $data = [$data];
277 | }
278 |
279 | // Load the table library
280 | $this->_CI->load->library('table');
281 |
282 | $this->_CI->table->set_heading($headings);
283 |
284 | foreach ($data as $row)
285 | {
286 | // Suppressing the "array to string conversion" notice
287 | // Keep the "evil" @ here
288 | $row = @array_map('strval', $row);
289 |
290 | $this->_CI->table->add_row($row);
291 | }
292 |
293 | return $this->_CI->table->generate();
294 | }
295 |
296 | /**
297 | * @link http://www.metashock.de/2014/02/create-csv-file-in-memory-php/
298 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed
299 | * to the constructor
300 | * @param string $delimiter The optional delimiter parameter sets the field
301 | * delimiter (one character only). NULL will use the default value (,)
302 | * @param string $enclosure The optional enclosure parameter sets the field
303 | * enclosure (one character only). NULL will use the default value (")
304 | * @return string A csv string
305 | */
306 | public function to_csv($data = NULL, $delimiter = ',', $enclosure = '"')
307 | {
308 | // Use a threshold of 1 MB (1024 * 1024)
309 | $handle = fopen('php://temp/maxmemory:1048576', 'w');
310 | if ($handle === FALSE)
311 | {
312 | return NULL;
313 | }
314 |
315 | // If no data is passed as a parameter, then use the data passed
316 | // via the constructor
317 | if ($data === NULL && func_num_args() === 0)
318 | {
319 | $data = $this->_data;
320 | }
321 |
322 | // If NULL, then set as the default delimiter
323 | if ($delimiter === NULL)
324 | {
325 | $delimiter = ',';
326 | }
327 |
328 | // If NULL, then set as the default enclosure
329 | if ($enclosure === NULL)
330 | {
331 | $enclosure = '"';
332 | }
333 |
334 | // Cast as an array if not already
335 | if (is_array($data) === FALSE)
336 | {
337 | $data = (array) $data;
338 | }
339 |
340 | // Check if it's a multi-dimensional array
341 | if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE))
342 | {
343 | // Multi-dimensional array
344 | $headings = array_keys($data[0]);
345 | }
346 | else
347 | {
348 | // Single array
349 | $headings = array_keys($data);
350 | $data = [$data];
351 | }
352 |
353 | // Apply the headings
354 | fputcsv($handle, $headings, $delimiter, $enclosure);
355 |
356 | foreach ($data as $record)
357 | {
358 | // If the record is not an array, then break. This is because the 2nd param of
359 | // fputcsv() should be an array
360 | if (is_array($record) === FALSE)
361 | {
362 | break;
363 | }
364 |
365 | // Suppressing the "array to string conversion" notice.
366 | // Keep the "evil" @ here.
367 | $record = @ array_map('strval', $record);
368 |
369 | // Returns the length of the string written or FALSE
370 | fputcsv($handle, $record, $delimiter, $enclosure);
371 | }
372 |
373 | // Reset the file pointer
374 | rewind($handle);
375 |
376 | // Retrieve the csv contents
377 | $csv = stream_get_contents($handle);
378 |
379 | // Close the handle
380 | fclose($handle);
381 |
382 | return $csv;
383 | }
384 |
385 | /**
386 | * Encode data as json
387 | *
388 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed
389 | * to the constructor
390 | * @return string Json representation of a value
391 | */
392 | public function to_json($data = NULL)
393 | {
394 | // If no data is passed as a parameter, then use the data passed
395 | // via the constructor
396 | if ($data === NULL && func_num_args() === 0)
397 | {
398 | $data = $this->_data;
399 | }
400 |
401 | // Get the callback parameter (if set)
402 | $callback = $this->_CI->input->get('callback');
403 |
404 | if (empty($callback) === TRUE)
405 | {
406 | return json_encode($data);
407 | }
408 |
409 | // We only honour a jsonp callback which are valid javascript identifiers
410 | elseif (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback))
411 | {
412 | // Return the data as encoded json with a callback
413 | return $callback.'('.json_encode($data).');';
414 | }
415 |
416 | // An invalid jsonp callback function provided.
417 | // Though I don't believe this should be hardcoded here
418 | $data['warning'] = 'INVALID JSONP CALLBACK: '.$callback;
419 |
420 | return json_encode($data);
421 | }
422 |
423 | /**
424 | * Encode data as a serialized array
425 | *
426 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed
427 | * to the constructor
428 | * @return string Serialized data
429 | */
430 | public function to_serialized($data = NULL)
431 | {
432 | // If no data is passed as a parameter, then use the data passed
433 | // via the constructor
434 | if ($data === NULL && func_num_args() === 0)
435 | {
436 | $data = $this->_data;
437 | }
438 |
439 | return serialize($data);
440 | }
441 |
442 | /**
443 | * Format data using a PHP structure
444 | *
445 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed
446 | * to the constructor
447 | * @return mixed String representation of a variable
448 | */
449 | public function to_php($data = NULL)
450 | {
451 | // If no data is passed as a parameter, then use the data passed
452 | // via the constructor
453 | if ($data === NULL && func_num_args() === 0)
454 | {
455 | $data = $this->_data;
456 | }
457 |
458 | return var_export($data, TRUE);
459 | }
460 |
461 | // INTERNAL FUNCTIONS
462 |
463 | /**
464 | * @param string $data XML string
465 | * @return array XML element object; otherwise, empty array
466 | */
467 | protected function _from_xml($data)
468 | {
469 | return $data ? (array) simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA) : [];
470 | }
471 |
472 | /**
473 | * @param string $data CSV string
474 | * @param string $delimiter The optional delimiter parameter sets the field
475 | * delimiter (one character only). NULL will use the default value (,)
476 | * @param string $enclosure The optional enclosure parameter sets the field
477 | * enclosure (one character only). NULL will use the default value (")
478 | * @return array A multi-dimensional array with the outer array being the number of rows
479 | * and the inner arrays the individual fields
480 | */
481 | protected function _from_csv($data, $delimiter = ',', $enclosure = '"')
482 | {
483 | // If NULL, then set as the default delimiter
484 | if ($delimiter === NULL)
485 | {
486 | $delimiter = ',';
487 | }
488 |
489 | // If NULL, then set as the default enclosure
490 | if ($enclosure === NULL)
491 | {
492 | $enclosure = '"';
493 | }
494 |
495 | return str_getcsv($data, $delimiter, $enclosure);
496 | }
497 |
498 | /**
499 | * @param string $data Encoded json string
500 | * @return mixed Decoded json string with leading and trailing whitespace removed
501 | */
502 | protected function _from_json($data)
503 | {
504 | return json_decode(trim($data));
505 | }
506 |
507 | /**
508 | * @param string $data Data to unserialize
509 | * @return mixed Unserialized data
510 | */
511 | protected function _from_serialize($data)
512 | {
513 | return unserialize(trim($data));
514 | }
515 |
516 | /**
517 | * @param string $data Data to trim leading and trailing whitespace
518 | * @return string Data with leading and trailing whitespace removed
519 | */
520 | protected function _from_php($data)
521 | {
522 | return trim($data);
523 | }
524 | }
525 |
--------------------------------------------------------------------------------
/documentation/class-Example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Class Example
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
73 |
74 |
75 |
76 |
77 | Overview
78 |
79 |
80 | Package
81 |
82 | Class
83 |
84 |
86 |
88 |
89 |
90 |
91 |
Class Example
92 |
93 |
94 |
95 |
This is an example of a few basic user interaction methods you could use
96 | all done with a hardcoded array
97 |
98 |
99 |
100 |
101 | CI_Controller
102 |
103 |
104 |
105 |
106 |
107 | REST_Controller
108 |
109 |
110 |
111 |
112 |
113 |
114 | Example
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
144 |
145 |
146 |
147 |
148 | Methods summary
149 |
150 |
151 |
152 | public
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
#
161 |
__construct ( string $config ,… )
162 |
163 |
164 |
Constructor for the REST API
165 |
166 |
167 |
168 |
Constructor for the REST API
169 |
170 |
171 |
Parameters
172 |
173 | $config ,…
174 | Configuration filename minus the file extension
175 | e.g: my_rest.php is passed as 'my_rest'
176 |
177 |
178 |
179 |
180 |
181 |
Overrides
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 | public
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
#
199 |
users_get ( )
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 | public
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
#
229 |
users_post ( )
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 | public
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
#
259 |
users_delete ( )
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 | Methods inherited from REST_Controller
281 |
282 |
283 | __destruct() ,
284 | _auth_override_check() ,
285 | _check_access() ,
286 | _check_blacklist_auth() ,
287 | _check_cors() ,
288 | _check_limit() ,
289 | _check_login() ,
290 | _check_php_session() ,
291 | _check_whitelist_auth() ,
292 | _detect_api_key() ,
293 | _detect_input_format() ,
294 | _detect_lang() ,
295 | _detect_method() ,
296 | _detect_output_format() ,
297 | _force_login() ,
298 | _get_default_output_format() ,
299 | _log_access_time() ,
300 | _log_request() ,
301 | _log_response_code() ,
302 | _parse_delete() ,
303 | _parse_get() ,
304 | _parse_head() ,
305 | _parse_options() ,
306 | _parse_patch() ,
307 | _parse_post() ,
308 | _parse_put() ,
309 | _parse_query() ,
310 | _perform_ldap_auth() ,
311 | _perform_library_auth() ,
312 | _prepare_basic_auth() ,
313 | _prepare_digest_auth() ,
314 | _remap() ,
315 | _xss_clean() ,
316 | delete() ,
317 | early_checks() ,
318 | get() ,
319 | head() ,
320 | options() ,
321 | patch() ,
322 | post() ,
323 | put() ,
324 | query() ,
325 | response() ,
326 | set_response() ,
327 | validation_errors()
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 | Constants inherited from REST_Controller
341 |
342 |
343 | HTTP_ACCEPTED ,
344 | HTTP_ALREADY_REPORTED ,
345 | HTTP_BAD_GATEWAY ,
346 | HTTP_BAD_REQUEST ,
347 | HTTP_CONFLICT ,
348 | HTTP_CONTINUE ,
349 | HTTP_CREATED ,
350 | HTTP_EXPECTATION_FAILED ,
351 | HTTP_FAILED_DEPENDENCY ,
352 | HTTP_FORBIDDEN ,
353 | HTTP_FOUND ,
354 | HTTP_GATEWAY_TIMEOUT ,
355 | HTTP_GONE ,
356 | HTTP_IM_USED ,
357 | HTTP_INSUFFICIENT_STORAGE ,
358 | HTTP_INTERNAL_SERVER_ERROR ,
359 | HTTP_I_AM_A_TEAPOT ,
360 | HTTP_LENGTH_REQUIRED ,
361 | HTTP_LOCKED ,
362 | HTTP_LOOP_DETECTED ,
363 | HTTP_METHOD_NOT_ALLOWED ,
364 | HTTP_MOVED_PERMANENTLY ,
365 | HTTP_MULTIPLE_CHOICES ,
366 | HTTP_MULTI_STATUS ,
367 | HTTP_NETWORK_AUTHENTICATION_REQUIRED ,
368 | HTTP_NON_AUTHORITATIVE_INFORMATION ,
369 | HTTP_NOT_ACCEPTABLE ,
370 | HTTP_NOT_EXTENDED ,
371 | HTTP_NOT_FOUND ,
372 | HTTP_NOT_IMPLEMENTED ,
373 | HTTP_NOT_MODIFIED ,
374 | HTTP_NO_CONTENT ,
375 | HTTP_OK ,
376 | HTTP_PARTIAL_CONTENT ,
377 | HTTP_PAYMENT_REQUIRED ,
378 | HTTP_PERMANENTLY_REDIRECT ,
379 | HTTP_PRECONDITION_FAILED ,
380 | HTTP_PRECONDITION_REQUIRED ,
381 | HTTP_PROCESSING ,
382 | HTTP_PROXY_AUTHENTICATION_REQUIRED ,
383 | HTTP_REQUESTED_RANGE_NOT_SATISFIABLE ,
384 | HTTP_REQUEST_ENTITY_TOO_LARGE ,
385 | HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE ,
386 | HTTP_REQUEST_TIMEOUT ,
387 | HTTP_REQUEST_URI_TOO_LONG ,
388 | HTTP_RESERVED ,
389 | HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL ,
390 | HTTP_RESET_CONTENT ,
391 | HTTP_SEE_OTHER ,
392 | HTTP_SERVICE_UNAVAILABLE ,
393 | HTTP_SWITCHING_PROTOCOLS ,
394 | HTTP_TEMPORARY_REDIRECT ,
395 | HTTP_TOO_MANY_REQUESTS ,
396 | HTTP_UNAUTHORIZED ,
397 | HTTP_UNPROCESSABLE_ENTITY ,
398 | HTTP_UNSUPPORTED_MEDIA_TYPE ,
399 | HTTP_UPGRADE_REQUIRED ,
400 | HTTP_USE_PROXY ,
401 | HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL ,
402 | HTTP_VERSION_NOT_SUPPORTED
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 | Properties inherited from REST_Controller
412 |
413 |
414 | $_allow ,
415 | $_apiuser ,
416 | $_args ,
417 | $_delete_args ,
418 | $_enable_xss ,
419 | $_end_rtime ,
420 | $_get_args ,
421 | $_head_args ,
422 | $_insert_id ,
423 | $_options_args ,
424 | $_patch_args ,
425 | $_post_args ,
426 | $_put_args ,
427 | $_query_args ,
428 | $_start_rtime ,
429 | $_supported_formats ,
430 | $_user_ldap_dn ,
431 | $allowed_http_methods ,
432 | $check_cors ,
433 | $http_status_codes ,
434 | $methods ,
435 | $request ,
436 | $response ,
437 | $rest ,
438 | $rest_format
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
--------------------------------------------------------------------------------
/documentation/source-class-Example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | File controllers/api/Example.php
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
78 |
79 |
80 |
81 |
82 | Overview
83 |
84 |
85 | Package
86 |
87 | Class
88 |
89 |
91 |
93 |
94 |
95 |
1: <?php
96 | 2:
97 | 3: defined ('BASEPATH' ) OR exit ('No direct script access allowed' );
98 | 4:
99 | 5:
100 | 6: require APPPATH . '/libraries/REST_Controller.php' ;
101 | 7:
102 | 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
113 | 19: class Example extends REST_Controller {
114 | 20:
115 | 21: function __construct()
116 | 22: {
117 | 23:
118 | 24: parent::__construct();
119 | 25:
120 | 26:
121 | 27:
122 | 28: $this ->methods['user_get' ]['limit' ] = 500 ;
123 | 29: $this ->methods['user_post' ]['limit' ] = 100 ;
124 | 30: $this ->methods['user_delete' ]['limit' ] = 50 ;
125 | 31: }
126 | 32:
127 | 33: public function users_get()
128 | 34: {
129 | 35:
130 | 36: $users = [
131 | 37: ['id' => 1 , 'name' => 'John' , 'email' => 'john@example.com' , 'fact' => 'Loves coding' ],
132 | 38: ['id' => 2 , 'name' => 'Jim' , 'email' => 'jim@example.com' , 'fact' => 'Developed on CodeIgniter' ],
133 | 39: ['id' => 3 , 'name' => 'Jane' , 'email' => 'jane@example.com' , 'fact' => 'Lives in the USA' , ['hobbies' => ['guitar' , 'cycling' ]]],
134 | 40: ];
135 | 41:
136 | 42: $id = $this ->get('id' );
137 | 43:
138 | 44:
139 | 45:
140 | 46: if ($id === NULL )
141 | 47: {
142 | 48:
143 | 49: if ($users )
144 | 50: {
145 | 51:
146 | 52: $this ->response($users , REST_Controller::HTTP_OK);
147 | 53: }
148 | 54: else
149 | 55: {
150 | 56:
151 | 57: $this ->response([
152 | 58: 'status' => FALSE ,
153 | 59: 'message' => 'No users were found'
154 | 60: ], REST_Controller::HTTP_NOT_FOUND);
155 | 61: }
156 | 62: }
157 | 63:
158 | 64:
159 | 65:
160 | 66: $id = (int) $id ;
161 | 67:
162 | 68:
163 | 69: if ($id <= 0 )
164 | 70: {
165 | 71:
166 | 72: $this ->response(NULL , REST_Controller::HTTP_BAD_REQUEST);
167 | 73: }
168 | 74:
169 | 75:
170 | 76:
171 | 77:
172 | 78: $user = NULL ;
173 | 79:
174 | 80: if (!empty ($users ))
175 | 81: {
176 | 82: foreach ($users as $key => $value )
177 | 83: {
178 | 84: if (isset ($value ['id' ]) && $value ['id' ] === $id )
179 | 85: {
180 | 86: $user = $value ;
181 | 87: }
182 | 88: }
183 | 89: }
184 | 90:
185 | 91: if (!empty ($user ))
186 | 92: {
187 | 93: $this ->set_response($user , REST_Controller::HTTP_OK);
188 | 94: }
189 | 95: else
190 | 96: {
191 | 97: $this ->set_response([
192 | 98: 'status' => FALSE ,
193 | 99: 'message' => 'User could not be found'
194 | 100: ], REST_Controller::HTTP_NOT_FOUND);
195 | 101: }
196 | 102: }
197 | 103:
198 | 104: public function users_post()
199 | 105: {
200 | 106:
201 | 107: $message = [
202 | 108: 'id' => 100 ,
203 | 109: 'name' => $this ->post('name' ),
204 | 110: 'email' => $this ->post('email' ),
205 | 111: 'message' => 'Added a resource'
206 | 112: ];
207 | 113:
208 | 114: $this ->set_response($message , REST_Controller::HTTP_CREATED);
209 | 115: }
210 | 116:
211 | 117: public function users_delete()
212 | 118: {
213 | 119: $id = (int) $this ->get('id' );
214 | 120:
215 | 121:
216 | 122: if ($id <= 0 )
217 | 123: {
218 | 124:
219 | 125: $this ->response(NULL , REST_Controller::HTTP_BAD_REQUEST);
220 | 126: }
221 | 127:
222 | 128:
223 | 129: $message = [
224 | 130: 'id' => $id ,
225 | 131: 'message' => 'Deleted the resource'
226 | 132: ];
227 | 133:
228 | 134: $this ->set_response($message , REST_Controller::HTTP_NO_CONTENT);
229 | 135: }
230 | 136:
231 | 137: }
232 | 138:
233 |
234 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
--------------------------------------------------------------------------------
/documentation/class-Key.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Class Key
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
73 |
74 |
75 |
76 |
77 | Overview
78 |
79 |
80 | Package
81 |
82 | Class
83 |
84 |
86 |
88 |
89 |
90 |
91 |
Class Key
92 |
93 |
94 |
95 |
Keys Controller
96 | This is a basic Key Management REST controller to make and delete keys
97 |
98 |
99 |
100 |
101 | CI_Controller
102 |
103 |
104 |
105 |
106 |
107 | REST_Controller
108 |
109 |
110 |
111 |
112 |
113 |
114 | Key
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
144 |
145 |
146 |
147 |
148 | Methods summary
149 |
150 |
151 |
152 | public
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
#
161 |
index_put ( )
162 |
163 |
164 |
Insert a key into the database
165 |
166 |
167 |
168 |
Insert a key into the database
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 | public
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
#
191 |
index_delete ( )
192 |
193 |
194 |
Remove a key from the database to stop it working
195 |
196 |
197 |
198 |
Remove a key from the database to stop it working
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 | public
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
#
221 |
level_post ( )
222 |
223 |
224 |
Change the level
225 |
226 |
227 |
228 |
Change the level
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 | public
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
#
251 |
suspend_post ( )
252 |
253 |
254 |
Suspend a key
255 |
256 |
257 |
258 |
Suspend a key
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 | public
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
#
281 |
regenerate_post ( )
282 |
283 |
284 |
Regenerate a key
285 |
286 |
287 |
288 |
Regenerate a key
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 | Methods inherited from REST_Controller
303 |
304 |
305 | __construct() ,
306 | __destruct() ,
307 | _auth_override_check() ,
308 | _check_access() ,
309 | _check_blacklist_auth() ,
310 | _check_cors() ,
311 | _check_limit() ,
312 | _check_login() ,
313 | _check_php_session() ,
314 | _check_whitelist_auth() ,
315 | _detect_api_key() ,
316 | _detect_input_format() ,
317 | _detect_lang() ,
318 | _detect_method() ,
319 | _detect_output_format() ,
320 | _force_login() ,
321 | _get_default_output_format() ,
322 | _log_access_time() ,
323 | _log_request() ,
324 | _log_response_code() ,
325 | _parse_delete() ,
326 | _parse_get() ,
327 | _parse_head() ,
328 | _parse_options() ,
329 | _parse_patch() ,
330 | _parse_post() ,
331 | _parse_put() ,
332 | _parse_query() ,
333 | _perform_ldap_auth() ,
334 | _perform_library_auth() ,
335 | _prepare_basic_auth() ,
336 | _prepare_digest_auth() ,
337 | _remap() ,
338 | _xss_clean() ,
339 | delete() ,
340 | early_checks() ,
341 | get() ,
342 | head() ,
343 | options() ,
344 | patch() ,
345 | post() ,
346 | put() ,
347 | query() ,
348 | response() ,
349 | set_response() ,
350 | validation_errors()
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 | Constants inherited from REST_Controller
364 |
365 |
366 | HTTP_ACCEPTED ,
367 | HTTP_ALREADY_REPORTED ,
368 | HTTP_BAD_GATEWAY ,
369 | HTTP_BAD_REQUEST ,
370 | HTTP_CONFLICT ,
371 | HTTP_CONTINUE ,
372 | HTTP_CREATED ,
373 | HTTP_EXPECTATION_FAILED ,
374 | HTTP_FAILED_DEPENDENCY ,
375 | HTTP_FORBIDDEN ,
376 | HTTP_FOUND ,
377 | HTTP_GATEWAY_TIMEOUT ,
378 | HTTP_GONE ,
379 | HTTP_IM_USED ,
380 | HTTP_INSUFFICIENT_STORAGE ,
381 | HTTP_INTERNAL_SERVER_ERROR ,
382 | HTTP_I_AM_A_TEAPOT ,
383 | HTTP_LENGTH_REQUIRED ,
384 | HTTP_LOCKED ,
385 | HTTP_LOOP_DETECTED ,
386 | HTTP_METHOD_NOT_ALLOWED ,
387 | HTTP_MOVED_PERMANENTLY ,
388 | HTTP_MULTIPLE_CHOICES ,
389 | HTTP_MULTI_STATUS ,
390 | HTTP_NETWORK_AUTHENTICATION_REQUIRED ,
391 | HTTP_NON_AUTHORITATIVE_INFORMATION ,
392 | HTTP_NOT_ACCEPTABLE ,
393 | HTTP_NOT_EXTENDED ,
394 | HTTP_NOT_FOUND ,
395 | HTTP_NOT_IMPLEMENTED ,
396 | HTTP_NOT_MODIFIED ,
397 | HTTP_NO_CONTENT ,
398 | HTTP_OK ,
399 | HTTP_PARTIAL_CONTENT ,
400 | HTTP_PAYMENT_REQUIRED ,
401 | HTTP_PERMANENTLY_REDIRECT ,
402 | HTTP_PRECONDITION_FAILED ,
403 | HTTP_PRECONDITION_REQUIRED ,
404 | HTTP_PROCESSING ,
405 | HTTP_PROXY_AUTHENTICATION_REQUIRED ,
406 | HTTP_REQUESTED_RANGE_NOT_SATISFIABLE ,
407 | HTTP_REQUEST_ENTITY_TOO_LARGE ,
408 | HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE ,
409 | HTTP_REQUEST_TIMEOUT ,
410 | HTTP_REQUEST_URI_TOO_LONG ,
411 | HTTP_RESERVED ,
412 | HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL ,
413 | HTTP_RESET_CONTENT ,
414 | HTTP_SEE_OTHER ,
415 | HTTP_SERVICE_UNAVAILABLE ,
416 | HTTP_SWITCHING_PROTOCOLS ,
417 | HTTP_TEMPORARY_REDIRECT ,
418 | HTTP_TOO_MANY_REQUESTS ,
419 | HTTP_UNAUTHORIZED ,
420 | HTTP_UNPROCESSABLE_ENTITY ,
421 | HTTP_UNSUPPORTED_MEDIA_TYPE ,
422 | HTTP_UPGRADE_REQUIRED ,
423 | HTTP_USE_PROXY ,
424 | HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL ,
425 | HTTP_VERSION_NOT_SUPPORTED
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 | Properties summary
434 |
435 |
436 | protected
437 | array
438 |
439 |
440 |
441 | $methods
442 |
443 |
444 |
Defines the list of method properties such as limit, log and level
445 |
446 |
447 |
448 |
Defines the list of method properties such as limit, log and level
449 |
450 |
451 |
452 |
453 |
454 |
#
455 |
[
456 | 'index_put' => ['level' => 10 , 'limit' => 10 ],
457 | 'index_delete' => ['level' => 10 ],
458 | 'level_post' => ['level' => 10 ],
459 | 'regenerate_post' => ['level' => 10 ],
460 | ]
461 |
462 |
463 |
464 |
465 |
466 |
467 | Properties inherited from REST_Controller
468 |
469 |
470 | $_allow ,
471 | $_apiuser ,
472 | $_args ,
473 | $_delete_args ,
474 | $_enable_xss ,
475 | $_end_rtime ,
476 | $_get_args ,
477 | $_head_args ,
478 | $_insert_id ,
479 | $_options_args ,
480 | $_patch_args ,
481 | $_post_args ,
482 | $_put_args ,
483 | $_query_args ,
484 | $_start_rtime ,
485 | $_supported_formats ,
486 | $_user_ldap_dn ,
487 | $allowed_http_methods ,
488 | $check_cors ,
489 | $http_status_codes ,
490 | $request ,
491 | $response ,
492 | $rest ,
493 | $rest_format
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
--------------------------------------------------------------------------------