Test Failed
Push — master ( 696af1...07df9d )
by Jean-Christophe
09:00
created

RestServer::setAccessAllowOrigin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Ubiquity\controllers\rest;
4
5
use Ubiquity\controllers\Startup;
6
use Ubiquity\cache\ClassUtils;
7
use Ubiquity\cache\CacheManager;
8
use Ubiquity\exceptions\RestException;
9
use Ubiquity\log\Logger;
10
use Ubiquity\utils\http\URequest;
11
12
/**
13
 * Rest server base class.
14
 * Ubiquity\controllers\rest$RestServer
15
 * This class is part of Ubiquity
16
 *
17
 * @author jcheron <[email protected]>
18
 * @version 1.0.5
19
 *
20
 */
21
class RestServer {
22
	/**
23
	 *
24
	 * @var array
25
	 */
26
	protected $config;
27
	protected $headers;
28
	protected $tokensFolder;
29
	protected $tokensCacheKey = "_apiTokens";
30
	protected $allowedOrigins;
31
32
	/**
33
	 *
34
	 * @var ApiTokens
35
	 */
36 14
	protected $apiTokens;
37 14
38 14
	public function __construct(&$config, $headers = null) {
39 14
		$this->config = $config;
40
		$this->headers = [ 'Access-Control-Allow-Origin' => '*','Access-Control-Allow-Credentials' => 'true','Access-Control-Max-Age' => '86400','Access-Control-Allow-Methods' => 'GET, POST, OPTIONS, PUT, DELETE, PATCH, HEAD','Content-Type' => 'application/json; charset=utf8' ];
41
		if (is_array ( $headers )) {
42 14
			$this->headers = array_merge ( $this->headers, $headers );
43
		}
44 1
	}
45 1
46 1
	/**
47
	 * Establishes the connection with the server, returns an added token in the Authorization header of the request
48 1
	 * @return array
49 1
	 */
50 1
	public function connect() {
51 1
		if (! isset ( $this->apiTokens )) {
52
			$this->apiTokens = $this->_loadApiTokens ();
53
		}
54
		$token = $this->apiTokens->addToken ();
55
		$this->_addHeaderToken ( $token );
56
		return [ "access_token" => $token,"token_type" => "Bearer","expires_in" => $this->apiTokens->getDuration () ];
57
	}
58 1
59 1
	/**
60 1
	 * Check if token is valid
61
	 *
62
	 * @return boolean
63
	 */
64
	public function isValid() {
65
		$this->apiTokens = $this->_loadApiTokens ();
66
		$key = $this->_getHeaderToken ();
67
		if ($this->apiTokens->isExpired ( $key )) {
68
			return false;
69 1
		} else {
70 1
			$this->_addHeaderToken ( $key );
71 1
			return true;
72
		}
73
	}
74
75
	public function _getHeaderToken() {
76
		$authHeader = $this->_getHeader ( "Authorization" );
77
		if ($authHeader !== false) {
78
			$headerDatas = explode ( " ", $authHeader, 2 );
79
			if (sizeof ( $headerDatas ) === 2) {
80
				list ( $type, $data ) = $headerDatas;
81
				if (\strcasecmp ( $type, "Bearer" ) == 0) {
82
					return $data;
83
				} else {
84 1
					throw new RestException ( "Bearer is required in authorization header." );
85
				}
86
			} else {
87
				throw new RestException ( "The header Authorization is required in http headers." );
88 9
			}
89 9
		} else {
90 1
			throw new RestException ( "The header Authorization is required in http headers." );
91 1
		}
92
	}
93 9
94
	public function finalizeTokens() {
95 1
		if (isset ( $this->apiTokens )) {
96 1
			$this->apiTokens->removeExpireds ();
97 1
			$this->apiTokens->storeToCache ();
98
		}
99
	}
100 1
101
	public function _getHeader($header) {
102
		$headers = getallheaders ();
103 1
		if (isset ( $headers [$header] )) {
104 1
			return $headers [$header];
105 1
		}
106
		return false;
107
	}
108
109
	public function _addHeaderToken($token) {
110
		$this->_header ( "Authorization", "Bearer " . $token,true );
111
	}
112 2
113 2
114
	public function _loadApiTokens() {
115
		return $this->getApiTokens()->getFromCache ( CacheManager::getAbsoluteCacheDirectory () . \DS, $this->tokensCacheKey );
116
	}
117
	
118
	protected function getApiTokens(){
119
		if(!isset($this->apiTokens)){
120
			$this->apiTokens=$this->newApiTokens();
121
		}
122 14
		return $this->apiTokens;
123 14
	}
124 14
125 14
	/**
126
	 * To override for defining another ApiToken type
127
	 *
128
	 * @return ApiTokens
129 14
	 */
130 14
	protected function newApiTokens(){
131
		return new ApiTokens();
132
	}
133
	
134
	protected function getAllowedOrigin(){
135
		$http_origin = URequest::getOrigin();
136
		if(is_array($this->allowedOrigins)){
137 14
			if(array_search($http_origin, $this->allowedOrigins)!==false){
138 14
				return $http_origin;
139 14
			}
140
			return;
141 14
		}
142 14
		return '*';
143
	}
144 14
	
145 14
	protected function setAccessControlAllowOriginHeader(){
146 14
		$origin=$this->getAllowedOrigin();
147 14
		if(isset($origin)){
148 14
			$this->headers['Access-Control-Allow-Origin']=$origin;
149
			\header ( 'Access-Control-Allow-Origin: ' . $origin, true);
150
		}
151
	}
152
	
153
154
	/**
155
	 *
156
	 * @param string $headerField
157
	 * @param string $value
158
	 * @param boolean $replace
159 14
	 */
160
	public function _header($headerField, $value = null, $replace = null) {
161 1
		if (! isset ( $value )) {
162 1
			if (isset ( $this->headers [$headerField] )) {
163 1
				$value = $this->headers [$headerField];
164 1
			} else
165 1
				return;
166 1
		}
167
		\header ( trim ( $headerField ) . ": " . trim ( $value ), $replace );
168 1
	}
169
170
	/**
171
	 *
172
	 * @param string $contentType default application/json
173
	 * @param string $charset default utf8
174
	 */
175
	public function _setContentType($contentType = null, $charset = null) {
176
		$value = $contentType;
177
		if (isset ( $charset ))
178
			$value .= "; charset=" . $charset;
179
		$this->_header ( "Content-type", $value );
180
	}
181
182
	public function cors() {
183
		$this->setAccessControlAllowOriginHeader();
184
		$this->_header ( 'Access-Control-Allow-Credentials' );
185
		$this->_header ( 'Access-Control-Max-Age' );
186
		if ($_SERVER ['REQUEST_METHOD'] == 'OPTIONS') {
187
			if (isset ( $_SERVER ['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] ))
188
				$this->_header ( 'Access-Control-Allow-Methods' );
189
190
			if (isset ( $_SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'] )) {
191
				$this->_header ( 'Access-Control-Allow-Headers', $_SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'] );
192
			} else {
193
				$this->_header ( 'Access-Control-Allow-Headers', '*' );
194
			}
195
			Logger::info ( "Rest", "cors exit normally", "Cors" );
196
		}
197
	}
198
199
	public static function getRestNamespace() {
200
		$config = Startup::getConfig ();
201
		$controllerNS = $config ["mvcNS"] ["controllers"];
202
		$restNS = "";
203
		if (isset ( $config ["mvcNS"] ["rest"] )) {
204
			$restNS = $config ["mvcNS"] ["rest"];
205
		}
206
		return ClassUtils::getNamespaceFromParts ( [ $controllerNS,$restNS ] );
207
	}
208
209
	/**
210
	 * Adds an unique allowed origin for access control.
211
	 * @param string $address
212
	 */
213
	public function setAllowOrigin($address = '*') {
214
		if($address!=='*'){
215
			$this->allowedOrigins=[$address];
216
		}else{
217
			$this->allowedOrigins=[];
218
		}
219
	}
220
	
221
	/**
222
	 * Adds an allowed origin for access control.
223
	 * @param string $address
224
	 */
225
	public function addAllowOrigin($address) {
226
		$this->allowedOrigins=[$address];
227
	}
228
}
229