Test Failed
Push — master ( a3ba5a...4fa899 )
by Jean-Christophe
18:16
created

AuthController::_addFrmAjaxBehavior()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 6
ccs 0
cts 0
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Ubiquity\controllers\auth;
4
5
use Ubiquity\utils\http\USession;
6
use Ubiquity\utils\http\URequest;
7
use Ubiquity\utils\flash\FlashMessage;
8
use Ubiquity\controllers\Controller;
9
use Ubiquity\utils\http\UResponse;
10
use Ubiquity\utils\base\UString;
11
use Ubiquity\controllers\Startup;
12
use Ajax\service\Javascript;
13
use Ubiquity\utils\http\UCookie;
14
use Ubiquity\controllers\semantic\InsertJqueryTrait;
15
use Ajax\semantic\html\collections\form\HtmlForm;
16
use Ajax\semantic\components\validation\Rule;
17
use Ajax\php\ubiquity\JsUtils;
18
use Ubiquity\cache\CacheManager;
19
20
/**
21
 * Controller Auth
22
 *
23
 * @property \Ajax\php\ubiquity\JsUtils $jquery
24
 */
25
abstract class AuthController extends Controller {
26
	use AuthControllerCoreTrait,AuthControllerVariablesTrait,AuthControllerOverrideTrait,InsertJqueryTrait,AuthControllerValidationTrait;
27
28
	/**
29
	 *
30
	 * @var AuthFiles
31
	 */
32
	protected $authFiles;
33
	protected $_controller;
34
	protected $_action;
35
	protected $_actionParams;
36
	protected $_noAccessMsg;
37
	protected $_loginCaption;
38
	protected $_attemptsSessionKey = "_attempts";
39 1
	protected $_controllerInstance;
40 1
	protected $_compileJS = true;
41 1
	protected $_invalid=false;
42 1
43 1
	public function __construct($instance = null) {
44 1
		parent::__construct ();
45 1
		$this->_insertJquerySemantic ();
46 1
		$this->_controller = Startup::getController ();
47 1
		$this->_action = Startup::getAction ();
48 1
		$this->_actionParams = Startup::getActionParams ();
49
		$this->_noAccessMsg = new FlashMessage ( 'You are not authorized to access the page <b>{url}</b> !', "Forbidden access", 'error', 'warning circle' );
50 1
		$this->_loginCaption = 'Log in';
51
		$this->_controllerInstance = $instance;
52 1
		if (isset ( $instance ))
53 1
			Startup::injectDependences ( $instance );
54
	}
55
56
	public function index() {
57
		if (($nbAttempsMax = $this->attemptsNumber ()) !== null) {
58
			$nb = USession::getTmp ( $this->_attemptsSessionKey, $nbAttempsMax );
59
			if ($nb <= 0) {
60 1
				$this->badLogin ();
61 1
				return;
62
			}
63
		}
64
		if($this->useAjax()){
65
			$this->_addFrmAjaxBehavior('frm-login');
66
		}
67
		$vData=[ "action" => $this->getBaseUrl () . 'connect','loginInputName' => $this->_getLoginInputName (),'loginLabel' => $this->loginLabel (),'passwordInputName' => $this->_getPasswordInputName (),'passwordLabel' => $this->passwordLabel (),'rememberCaption' => $this->rememberCaption () ];
68 1
		$this->addAccountCreationViewData($vData,true);
69 1
		$this->authLoadView ( $this->_getFiles ()->getViewIndex (), $vData );
70
	}
71
	
72
	public function addAccount(){
73
		if($this->hasAccountCreation()){
74
			if($this->useAjax()){
75
				$frm=$this->_addFrmAjaxBehavior('frm-create');
76
				$passwordInputName=$this->_getPasswordInputName();
77 1
				$frm->addExtraFieldRules($passwordInputName.'-conf', ['empty',"match[$passwordInputName]"]);
78 1
				if($this->newAccountCreationRule('')!==null){
2 ignored issues
show
Bug introduced by
Are you sure the usage of $this->newAccountCreationRule('') targeting Ubiquity\controllers\aut...ewAccountCreationRule() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

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

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

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

Loading history...
introduced by
The condition $this->newAccountCreationRule('') !== null is always false.
Loading history...
79
					$this->jquery->exec(Rule::ajax($this->jquery, 'checkAccount', $this->getBaseUrl () . '/_newAccountCreationRule', '{}', 'result=data.result;', 'postForm', [
80
									'form' => 'frm-create'
81 1
							]), true);
82 1
					$frm->addExtraFieldRule($this->_getLoginInputName(), 'checkAccount','Account {value} is not available!');
83 1
				}
84 1
			}
85 1
			$this->authLoadView ( $this->_getFiles ()->getViewCreate(), [ 'action' => $this->getBaseUrl () . '/createAccount','loginInputName' => $this->_getLoginInputName (),'loginLabel' => $this->loginLabel (),'passwordInputName' => $this->_getPasswordInputName (),'passwordLabel' => $this->passwordLabel (),'passwordConfLabel'=>$this->passwordConfLabel(),'rememberCaption' => $this->rememberCaption () ] );
86
		}
87
	}
88
	
89
90 1
	public function createAccount(){
91 1
		$account=URequest::post($this->_getLoginInputName());
92
		$msgSup='';
93
		if($this->_create($account,URequest::post($this->_getPasswordInputName()))){
2 ignored issues
show
Bug introduced by
It seems like $account can also be of type null; however, parameter $login of Ubiquity\controllers\aut...thController::_create() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
		if($this->_create(/** @scrutinizer ignore-type */ $account,URequest::post($this->_getPasswordInputName()))){
Loading history...
Bug introduced by
It seems like Ubiquity\utils\http\UReq...getPasswordInputName()) can also be of type null; however, parameter $password of Ubiquity\controllers\aut...thController::_create() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
		if($this->_create($account,/** @scrutinizer ignore-type */ URequest::post($this->_getPasswordInputName()))){
Loading history...
94
			if($this->hasEmailValidation()){
95
				$email=$this->getEmailFromNewAccount($account);
96 1
				$this->prepareEmailValidation($email);
97 1
				$msgSup='<br>Confirm your email address by checking at <b>$email</b>.';
98 1
			}
99 1
			$msg=new FlashMessage ( '<b>{account}</b> account created with success!'.$msgSup, 'Account creation', 'success', 'check square' );
100
		}else{
101
			$msg=new FlashMessage ( 'The account <b>{account}</b> was not created!', 'Account creation', 'error', 'warning circle' );
102 1
		}
103
		$message=$this->fMessage($msg->parseContent(['account'=>$account]));
104
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), [ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ] );
105 1
	}
106
107 1
	/**
108 1
	 *
109 1
	 * {@inheritdoc}
110 1
	 * @see \Ubiquity\controllers\Controller::isValid()
111
	 */
112
	public final function isValid($action) {
113 1
		return true;
114
	}
115
116
	/**
117
	 * Action called when the user does not have access rights to a requested resource
118 1
	 *
119 1
	 * @param array|string $urlParts
120 1
	 */
121 1
	public function noAccess($urlParts) {
122 1
		if (! \is_array ( $urlParts )) {
123
			$urlParts = \explode ( '.', $urlParts );
124
		}
125
		USession::set ( 'urlParts', $urlParts );
126
		$fMessage = $this->_noAccessMsg;
127
		$this->noAccessMessage ( $fMessage );
128
		$message = $this->fMessage ( $fMessage->parseContent ( [ 'url' => \implode ( '/', $urlParts ) ] ) );
129
		
130
		if (URequest::isAjax ()) {
131
			$this->jquery->get ( $this->_getBaseRoute () . '/info/f', '#_userInfo', [ 'historize' => false,'jqueryDone' => 'replaceWith','hasLoader' => false,'attr' => '' ] );
132
			$this->jquery->compile ( $this->view );
133
		}
134
		
135
		$vData=[ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ];
136
		$this->addAccountCreationViewData($vData);
137
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), $vData);
138
	}
139 1
140 1
	/**
141 1
	 * Override to implement the complete connection procedure
142
	 */
143
	public function connect() {
144
		if (URequest::isPost ()) {
145
			if ($connected = $this->_connect ()) {
146
				if (isset ( $_POST ['ck-remember'] )) {
147 1
					$this->rememberMe ( $connected );
148 1
				}
149 1
				if (USession::exists ( $this->_attemptsSessionKey )) {
150 1
					USession::delete ( $this->_attemptsSessionKey );
151 1
				}
152 1
				if($this->has2FA($connected)){
153 1
					$this->initializeAuth();
154
					USession::set($this->_getUserSessionKey().'-2FA', $connected);
155
					$this->send2FACode();
156
					$this->confirm();
157
					$this->finalizeAuth();
158
				}else{
159
					$this->onConnect ( $connected );
160
				}
161
			} else {
162
				$this->_invalid=true;
163
				$this->initializeAuth();
164
				$this->onBadCreditentials ();
165
				$this->finalizeAuth();
166
			}
167
		}
168
	}
169
170
	/**
171
	 * Default Action for invalid creditentials
172 1
	 */
173 1
	public function badLogin() {
174
		$fMessage = new FlashMessage ( 'Invalid creditentials!', 'Connection problem', 'warning', 'warning circle' );
175
		$this->badLoginMessage ( $fMessage );
176 1
		$attemptsMessage = "";
177
		if (($nbAttempsMax = $this->attemptsNumber ()) !== null) {
178 1
			$nb = USession::getTmp ( $this->_attemptsSessionKey, $nbAttempsMax );
179
			$nb --;
180
			if ($nb < 0) {
181
				$nb = 0;
182
			}
183
			if ($nb == 0) {
184
				$fAttemptsNumberMessage = $this->noAttempts ();
185
			} else {
186
				$fAttemptsNumberMessage = new FlashMessage ( '<i class="ui warning icon"></i> You still have {_attemptsCount} attempts to log in.', null, 'bottom attached warning', '' );
187
			}
188
			USession::setTmp ( $this->_attemptsSessionKey, $nb, $this->attemptsTimeout () );
189
			$this->attemptsNumberMessage ( $fAttemptsNumberMessage, $nb );
190
			$fAttemptsNumberMessage->parseContent ( [ '_attemptsCount' => $nb,'_timer' => '<span id="timer"></span>' ] );
191
			$attemptsMessage = $this->fMessage ( $fAttemptsNumberMessage, 'timeout-message' );
192
			$fMessage->addType ( "attached" );
193
		}
194
		$message = $this->fMessage ( $fMessage, 'bad-login' ) . $attemptsMessage;
195
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), [ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ] );
196
	}
197
	
198
	/**
199
	 * Logout action
200
	 * Terminate the session and display a logout message
201
	 */
202
	public function terminate() {
203
		USession::terminate ();
204
		$fMessage = new FlashMessage ( 'You have been properly disconnected!', 'Logout', 'success', 'checkmark' );
205
		$this->terminateMessage ( $fMessage );
206
		$message = $this->fMessage ( $fMessage );
207
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), [ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ] );
208
	}
209
210 1
	public function _disConnected() {
211 1
		$fMessage = new FlashMessage ( 'You have been disconnected from the application!', 'Logout', '', 'sign out' );
212 1
		$this->disconnectedMessage ( $fMessage );
213
		$message = $this->fMessage ( $fMessage );
214
		$this->jquery->getOnClick ( '._signin', $this->getBaseUrl (), $this->_getBodySelector (), [ 'stopPropagation' => false,'preventDefault' => false ] );
215
		$this->jquery->execOn ( 'click', '._close', "window.open(window.location,'_self').close();" );
216
		return $this->jquery->renderView ( $this->_getFiles ()->getViewDisconnected (), [ "_title" => 'Session ended','_message' => $message ], true );
217
	}
218 1
219
	/**
220
	 * Action displaying the logged user information
221
	 * if _displayInfoAsString returns true, use _infoUser var in views to display user info
222
	 *
223
	 * @param null|boolean $force
224
	 * @return string|null
225
	 * @throws \Exception
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 1
		return $this->loadView ( $this->_getFiles ()->getViewInfo (), [ 'connected' => USession::get ( $this->_getUserSessionKey () ),'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector () ], $displayInfoAsString );
234 1
	}
235 1
	
236 1
	public function checkConnection() {
237
		UResponse::asJSON ();
238 1
		echo "{\"valid\":" . UString::getBooleanStr ( $this->_isValidUser () ) . "}";
239 1
	}
240 1
241
	/**
242
	 * Sets the default noAccess message
243 1
	 * Default : "You are not authorized to access the page <b>{url}</b> !"
244
	 *
245 1
	 * @param string $content
246 1
	 * @param string $title
247
	 * @param string $type
248
	 * @param string $icon
249
	 */
250
	public function _setNoAccessMsg($content, $title = NULL, $type = NULL, $icon = null) {
251
		$this->_noAccessMsg->setValues ( $content, $title, $type, $icon );
252
	}
253 1
254 1
	/**
255 1
	 *
256
	 * @param string $_loginCaption
257 1
	 */
258
	public function _setLoginCaption($_loginCaption) {
259 1
		$this->_loginCaption = $_loginCaption;
260 1
	}
261
262
	/**
263
	 * Auto connect the user
264
	 */
265
	public function _autoConnect() {
266 1
		$cookie = $this->getCookieUser ();
267 1
		if (isset ( $cookie )) {
268 1
			$user = $this->fromCookie ( $cookie );
269
			if (isset ( $user )) {
270 1
				USession::set ( $this->_getUserSessionKey (), $user );
271 1
			}
272
		}
273 1
	}
274 1
275
	/**
276
	 * Deletes the cookie for auto connection and returns to index
277
	 */
278
	public function forgetConnection() {
279
		UCookie::delete ( $this->_getUserSessionKey () );
280
		$this->index ();
281
	}
282
283
	/**
284
	 *
285
	 * {@inheritdoc}
286
	 * @see \Ubiquity\controllers\ControllerBase::finalize()
287
	 */
288
	public function finalize() {
289
		if (! UResponse::isJSON ()) {
290
			if(Startup::getAction()!=='connect') {
291
				$this->finalizeAuth();
292
			}
293
			$this->jquery->execAtLast ( "if($('#_userInfo').length){\$('#_userInfo').replaceWith(" . preg_replace ( "/$\R?^/m", "", Javascript::prep_element ( $this->info () ) ) . ");}" );
294
			if ($this->_compileJS) {
295
				echo $this->jquery->compile ();
296
			}
297
		}
298
	}
299
300
	protected function finalizeAuth() {
301
		if (!URequest::isAjax()) {
302
			$this->loadView('@activeTheme/main/vFooter.html');
303
		}
304
	}
305
306
	/**
307
	 *
308
	 * {@inheritdoc}
309
	 * @see \Ubiquity\controllers\ControllerBase::initialize()
310
	 */
311
	public function initialize() {
312
		if(Startup::getAction()!=='connect') {
313
			$this->initializeAuth();
314
		}
315
	}
316
317
	protected function initializeAuth() {
318
		if (!URequest::isAjax()) {
319
			$this->loadView('@activeTheme/main/vHeader.html');
320
		}
321
	}
322
323
	/**
324
	 *
325
	 * @param string $url
326
	 */
327
	public function _forward($url, $initialize = null, $finalize = null) {
328
		if (! isset ( $initialize )) {
329
			$initialize = (! isset ( $this->_controllerInstance ) || URequest::isAjax ());
330
		}
331
		if (! isset ( $finalize )) {
332
			$finalize = $initialize;
333
		}
334
		Startup::forward ( $url, $initialize, $finalize );
335
	}
336
	
337
	public function _addAjaxBehavior(JsUtils $jquery=null,$ajaxParameters=['hasLoader'=>'$(this).children(".button")','historize'=>false,'listenerOn'=>'body']){
338
		$jquery??=$this->jquery;
339
		$jquery->getHref('.ajax[data-target]','', $ajaxParameters);
340
		$jquery->postFormAction('.ui.form',$this->_getBodySelector(),$ajaxParameters);
341
	}
342
343
	public function _addFrmAjaxBehavior($id):HtmlForm{
344
		$frm=$this->jquery->semantic()->htmlForm($id);
345
		$frm->addExtraFieldRule($this->_getLoginInputName(),'empty');
346
		$frm->addExtraFieldRule($this->_getPasswordInputName(),'empty');
347
		$frm->setValidationParams(['inline'=>true,'on'=>'blur']);
348
		return $frm;
349
	}
350
}
351