Completed
Push — master ( ae286a...b99700 )
by Jean-Christophe
01:39
created

AuthController::getFiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
namespace Ubiquity\controllers\auth;
3
4
use Ubiquity\utils\http\USession;
5
use Ubiquity\utils\http\URequest;
6
use Ubiquity\utils\flash\FlashMessage;
7
use Ubiquity\controllers\ControllerBase;
8
use Ubiquity\controllers\Auth\AuthFiles;
9
use Ubiquity\cache\ClassUtils;
10
use Ubiquity\utils\http\UResponse;
11
use Ubiquity\utils\base\UString;
12
use Ubiquity\controllers\Startup;
13
use Ubiquity\utils\http\UCookie;
14
use Ajax\service\Javascript;
15
16
 /**
17
 * Controller Auth
18
 * @property \Ajax\php\ubiquity\JsUtils $jquery
19
 **/
20
abstract class AuthController extends ControllerBase{
21
	use AuthControllerVariablesTrait;
22
	
23
	/**
24
	 * @var AuthFiles
25
	 */
26
	protected $authFiles;
27
	protected $_controller;
28
	protected $_action;
29
	protected $_actionParams;
30
	protected $_noAccessMsg;
31
	protected $_loginCaption;
32
	protected $_attemptsSessionKey="_attempts";
33
	protected $_controllerInstance;
34
	
35
	public function __construct($instance=null){
36
		parent::__construct();
37
		$this->_controller=Startup::getController();
38
		$this->_action=Startup::getAction();
39
		$this->_actionParams=Startup::getActionParams();
40
		$this->_noAccessMsg=new FlashMessage("You are not authorized to access the page <b>{url}</b> !","Forbidden access","error","warning circle");
41
		$this->_loginCaption="Log in";
42
		$this->_controllerInstance=$instance;
43
		if(isset($instance))
44
			Startup::injectDependences($instance, Startup::getConfig());
45
	}
46
	
47
	public function index(){
48
		if(($nbAttempsMax=$this->attemptsNumber())!==null){
1 ignored issue
show
Bug introduced by
Are you sure the assignment to $nbAttempsMax is correct as $this->attemptsNumber() (which targets Ubiquity\controllers\aut...Trait::attemptsNumber()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
49
			$nb=USession::getTmp($this->_attemptsSessionKey,$nbAttempsMax);
50
			if($nb<=0){
51
				$this->badLogin();
52
				return;
53
			}
54
		}
55
		$this->authLoadView($this->_getFiles()->getViewIndex(),["action"=>$this->getBaseUrl()."/connect",
56
				"loginInputName"=>$this->_getLoginInputName(),"loginLabel"=>$this->loginLabel(),
57
				"passwordInputName"=>$this->_getPasswordInputName(),"passwordLabel"=>$this->passwordLabel(),
58
				"rememberCaption"=>$this->rememberCaption()
59
		]);
60
	}
61
	
62
	/**
63
	 * To override
64
	 * Return the base route for this Auth controller
65
	 * @return string
66
	 */
67
	public function _getBaseRoute(){
68
		return ClassUtils::getClassSimpleName(get_class($this));
69
	}
70
	
71
	private function getBaseUrl(){
72
		return URequest::getUrl($this->_getBaseRoute());
73
	}
74
	/**
75
	 * {@inheritDoc}
76
	 * @see \controllers\ControllerBase::isValid()
77
	 */
78
	public final function isValid($action) {
79
		return true;
80
	}
81
	
82
	/**
83
	 * Action called when the user does not have access rights to a requested resource
84
	 * @param array|string $urlParts
85
	 */
86
	public function noAccess($urlParts){
87
		if(!is_array($urlParts)){
88
			$urlParts=explode(".", $urlParts);
89
		}
90
		USession::set("urlParts", $urlParts);
91
		$fMessage=$this->_noAccessMsg;
92
		$this->noAccessMessage($fMessage);
93
		$message=$this->fMessage($fMessage->parseContent(["url"=>implode("/",$urlParts)]));
94
		/*if(URequest::isAjax()){
95
			$this->jquery->get($this->_getBaseRoute()."/info/f","#_userInfo",["historize"=>false,"jqueryDone"=>"replaceWith","hasLoader"=>false,"attr"=>""]);
96
			$this->jquery->compile($this->view);
97
		}*/
98
		$this->authLoadView($this->_getFiles()->getViewNoAccess(),["_message"=>$message,"authURL"=>$this->getBaseUrl(),"bodySelector"=>$this->_getBodySelector(),"_loginCaption"=>$this->_loginCaption]);
99
	}
100
	
101
102
	
103
	/**
104
	 * Override to implement the complete connection procedure 
105
	 */
106
	public function connect(){
107
		if(URequest::isPost()){
108
			if($connected=$this->_connect()){
109
				if(isset($_POST["ck-remember"])){
110
					$this->rememberMe($connected);
111
				}
112
				if(USession::exists($this->_attemptsSessionKey)){
113
					USession::delete($this->_attemptsSessionKey);
114
				}
115
				$this->onConnect($connected);
116
			}else{
117
				$this->onBadCreditentials();
118
			}
119
		}
120
	}
121
	
122
	/**
123
	 * Processes the data posted by the login form
124
	 * Have to return the connected user instance
125
	 */
126
	abstract protected function _connect();
127
	
128
	/**
129
	 * @param object $connected
130
	 */
131
	abstract protected function onConnect($connected);
132
	
133
	/**
134
	 * To override for defining a new action when creditentials are invalid
135
	 */
136
	protected function onBadCreditentials(){
137
		$this->badLogin();
138
	}
139
	
140
	/**
141
	 * Default Action for invalid creditentials
142
	 */
143
	public function badLogin(){
144
		$fMessage=new FlashMessage("Invalid creditentials!","Connection problem","warning","warning circle");
145
		$this->badLoginMessage($fMessage);
146
		$attemptsMessage="";
147
		if(($nbAttempsMax=$this->attemptsNumber())!==null){
1 ignored issue
show
Bug introduced by
Are you sure the assignment to $nbAttempsMax is correct as $this->attemptsNumber() (which targets Ubiquity\controllers\aut...Trait::attemptsNumber()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
148
			$nb=USession::getTmp($this->_attemptsSessionKey,$nbAttempsMax);
149
			$nb--;
150
			if($nb<0) $nb=0;
151
			if($nb==0){
152
				$fAttemptsNumberMessage=$this->noAttempts();
153
			}else{
154
				$fAttemptsNumberMessage=new FlashMessage("<i class='ui warning icon'></i> You still have {_attemptsCount} attempts to log in.",null,"bottom attached warning","");
155
			}
156
			USession::setTmp($this->_attemptsSessionKey, $nb,$this->attemptsTimeout());
157
			$this->attemptsNumberMessage($fAttemptsNumberMessage,$nb);
158
			$fAttemptsNumberMessage->parseContent(["_attemptsCount"=>$nb,"_timer"=>"<span id='timer'></span>"]);
159
			$attemptsMessage=$this->fMessage($fAttemptsNumberMessage,"timeout-message");
160
			$fMessage->addType("attached");
161
		}
162
		$message=$this->fMessage($fMessage,"bad-login").$attemptsMessage;
163
		$this->authLoadView($this->_getFiles()->getViewNoAccess(),["_message"=>$message,"authURL"=>$this->getBaseUrl(),"bodySelector"=>$this->_getBodySelector(),"_loginCaption"=>$this->_loginCaption]);
164
	}
165
	
166
	protected function noAttempts(){
167
		$timeout=$this->attemptsTimeout();
168
		$plus="";
169
		if(is_numeric($timeout)){
170
			$this->jquery->exec("$('._login').addClass('disabled');",true);
171
			$plus=" You can try again {_timer}";
172
			$this->jquery->exec("var startTimer=function(duration, display) {var timer = duration, minutes, seconds;
173
    										var interval=setInterval(function () {
174
        										minutes = parseInt(timer / 60, 10);seconds = parseInt(timer % 60, 10);
175
										        minutes = minutes < 10 ? '0' + minutes : minutes;
176
        										seconds = seconds < 10 ? '0' + seconds : seconds;
177
										        display.html(minutes + ':' + seconds);
178
										        if (--timer < 0) {clearInterval(interval);$('#timeout-message').hide();$('#bad-login').removeClass('attached');$('._login').removeClass('disabled');}
179
    										}, 1000);
180
										}",true);
181
			$timeToLeft=USession::getTimeout($this->_attemptsSessionKey);
182
			$this->jquery->exec("startTimer({$timeToLeft},$('#timer'));",true);
183
			$this->jquery->compile($this->view);
184
		}
185
		return new FlashMessage("<i class='ui warning icon'></i> You have no more attempt of connection !".$plus,null,"bottom attached error","");
186
	}
187
	
188
189
	private function authLoadView($viewName,$vars=[]){
190
		$files=$this->_getFiles();
191
		$mainTemplate=$files->getBaseTemplate();
192
		if(isset($mainTemplate)){
193
			$vars["_viewname"]=$viewName;
194
			$vars["_base"]=$mainTemplate;
195
			$this->loadView($files->getViewBaseTemplate(),$vars);
196
		}else{
197
			$this->loadView($viewName,$vars);
198
		}
199
	}
200
	
201
	/**
202
	 * Logout action
203
	 * Terminate the session and display a logout message
204
	 */
205
	public function terminate(){
206
		USession::terminate();
207
		$fMessage=new FlashMessage("You have been properly disconnected!","Logout","success","checkmark");
208
		$this->terminateMessage($fMessage);
209
		$message=$this->fMessage($fMessage);
210
		$this->authLoadView($this->_getFiles()->getViewNoAccess(),["_message"=>$message,"authURL"=>$this->getBaseUrl(),"bodySelector"=>$this->_getBodySelector(),"_loginCaption"=>$this->_loginCaption]);
211
	}
212
	
213
	public function _disConnected(){
214
		$fMessage=new FlashMessage("You have been disconnected from the application!","Logout","","sign out");
215
		$this->disconnectedMessage($fMessage);
216
		$message=$this->fMessage($fMessage);
217
		$this->jquery->getOnClick("._signin", $this->getBaseUrl(),$this->_getBodySelector(),["stopPropagation"=>false,"preventDefault"=>false]);
218
		$this->jquery->execOn("click", "._close", "window.open(window.location,'_self').close();");
219
		return $this->jquery->renderView($this->_getFiles()->getViewDisconnected(),["_title"=>"Session ended","_message"=>$message],true);
220
	}
221
	
222
	/**
223
	 * Action displaying the logged user information 
224
	 * if _displayInfoAsString returns true, use _infoUser var in views to display user info
225
	 * @return string|null
226
	 */
227
	public function info($force=null){
228
		if(isset($force)){
229
			$displayInfoAsString=($force===true)?true:false;
230
		}else{
231
			$displayInfoAsString=$this->_displayInfoAsString();
232
		}
233
		return $this->loadView($this->_getFiles()->getViewInfo(),["connected"=>USession::get($this->_getUserSessionKey()),"authURL"=>$this->getBaseUrl(),"bodySelector"=>$this->_getBodySelector()],$displayInfoAsString);
234
	}
235
	
236
	protected function fMessage(FlashMessage $fMessage,$id=null){
237
		return $this->message($fMessage->getType(), $fMessage->getTitle(), $fMessage->getContent(),$fMessage->getIcon(),$id);
238
	}
239
	
240
	public function message($type,$header,$body,$icon="info",$id=null){
241
		return $this->loadView($this->_getFiles()->getViewMessage(),get_defined_vars(),true);
242
	}
243
	
244
	protected function getOriginalURL(){
245
		return USession::get("urlParts");
246
	}
247
	
248
	/**
249
	 * To override for defining user session key, default : "activeUser"
250
	 * @return string
251
	 */
252
	public function _getUserSessionKey(){
253
		return "activeUser";
254
	}
255
	
256
	/**
257
	 * To override for getting active user, default : USession::get("activeUser")
258
	 * @return string
259
	 */
260
	public function _getActiveUser(){
261
		return USession::get($this->_getUserSessionKey());
262
	}
263
	
264
	public function checkConnection(){
265
		UResponse::asJSON();
266
		echo "{\"valid\":".UString::getBooleanStr($this->_isValidUser())."}";
267
	}
268
	
269
	/**
270
	 * return boolean true if activeUser is valid
271
	 */
272
	abstract public function _isValidUser();
273
	
274
	/**
275
	 * To override for changing view files
276
	 * @return AuthFiles
277
	 */
278
	protected function getFiles ():AuthFiles{
279
		return new AuthFiles();
280
	}
281
	
282
	private function _getFiles():AuthFiles{
283
		if(!isset($this->authFiles)){
284
			$this->authFiles=$this->getFiles();
285
		}
286
		return $this->authFiles;
287
	}
288
	
289
	/**
290
	 * Sets the default noAccess message
291
	 * Default : "You are not authorized to access the page <b>{url}</b> !"
292
	 * @param string $content
293
	 * @param string $title
294
	 * @param string $type
295
	 * @param string $icon
296
	 */
297
	public function _setNoAccessMsg($content,$title=NULL,$type=NULL,$icon=null) {
298
		$this->_noAccessMsg->setValues($content,$title,$type,$icon);
299
	}
300
	/**
301
	 * @param string $_loginCaption
302
	 */
303
	public function _setLoginCaption($_loginCaption) {
304
		$this->_loginCaption = $_loginCaption;
305
	}
306
	
307
	protected function getViewVars($viewname){
308
		return ["authURL"=>$this->getBaseUrl(),"bodySelector"=>$this->_getBodySelector(),"_loginCaption"=>$this->_loginCaption];
309
	}
310
	
311
	/**
312
	 * Saves the connected user identifier in a cookie
313
	 * @param object $connected
314
	 */
315
	protected function rememberMe($connected){
316
		$id= $this->toCookie($connected);
317
		if(isset($id)){
318
			UCookie::set($this->_getUserSessionKey(),$id);
319
		}
320
	}
321
	
322
	/**
323
	 * Returns the cookie for auto connection
324
	 * @return NULL|string
325
	 */
326
	protected function getCookieUser(){
327
		return UCookie::get($this->_getUserSessionKey());
328
	}
329
	
330
	/**
331
	 * Returns the value from connected user to save it in the cookie for auto connection
332
	 * @param object $connected
333
	 */
334
	protected function toCookie($connected){
335
		return;
336
	}
337
	
338
	/**
339
	 * Loads the user from database using the cookie value
340
	 * @param string $cookie
341
	 */
342
	protected function fromCookie($cookie){
343
		return;
344
	}
345
	
346
	/**
347
	 * Auto connect the user
348
	 */
349
	public function _autoConnect() {
350
		$cookie=$this->getCookieUser();
351
		if(isset($cookie)){
352
			$user=$this->fromCookie($cookie);
353
			if(isset($user)){
354
				USession::set($this->_getUserSessionKey(), $user);
355
			}
356
		}
357
	}
358
	/**
359
	 * Deletes the cookie for auto connection and returns to index
360
	 */
361
	public function forgetConnection(){
362
		UCookie::delete($this->_getUserSessionKey());
363
		$this->index();
364
	}
365
	/**
366
	 * {@inheritDoc}
367
	 * @see \Ubiquity\controllers\ControllerBase::finalize()
368
	 */
369
	public function finalize() {
370
		if(!UResponse::isJSON()){
371 View Code Duplication
			if(!URequest::isAjax()){
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
372
				if(isset($this->_controllerInstance)){
373
					call_user_func_array(array($this->_controllerInstance, 'parent::finalize'), []);
374
				}else{
375
					parent::finalize();	
376
				}
377
			}
378
			$this->jquery->execAtLast("if($('#_userInfo').length){\$('#_userInfo').html(".preg_replace("/$\R?^/m", "",Javascript::prep_element($this->info())).");}");
379
			echo $this->jquery->compile();
380
		}
381
	}
382
383
	/**
384
	 * {@inheritDoc}
385
	 * @see \Ubiquity\controllers\ControllerBase::initialize()
386
	 */
387
	public function initialize() {
388 View Code Duplication
		if(!URequest::isAjax()){
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
389
			if(isset($this->_controllerInstance)){
390
				call_user_func_array(array($this->_controllerInstance, 'parent::initialize'), []);
391
			}else{
392
				parent::initialize();
393
			}
394
		}
395
	}
396
	
397
	/**
398
	 * @param string $url
399
	 */
400
	public function _forward($url){
401
		$initFinalize=true;
402
		if(isset($this->_controllerInstance) && !URequest::isAjax()){
403
			$initFinalize=false;
404
		}
405
		Startup::forward($url,$initFinalize,$initFinalize);
406
	}
407
408
}
409