Passed
Push — master ( df4f71...b35ad3 )
by Jean-Christophe
18:08
created

AuthController::isValid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Ubiquity\controllers\auth;
4
5
use Ubiquity\controllers\auth\traits\Auth2FATrait;
6
use Ubiquity\controllers\auth\traits\AuthAccountCreationTrait;
7
use Ubiquity\controllers\auth\traits\AuthAccountRecoveryTrait;
8
use Ubiquity\utils\http\USession;
9
use Ubiquity\utils\http\URequest;
10
use Ubiquity\utils\flash\FlashMessage;
11
use Ubiquity\controllers\Controller;
12
use Ubiquity\utils\http\UResponse;
13
use Ubiquity\utils\base\UString;
14
use Ubiquity\controllers\Startup;
15
use Ajax\service\Javascript;
16
use Ubiquity\utils\http\UCookie;
17
use Ubiquity\controllers\semantic\InsertJqueryTrait;
18
use Ajax\semantic\html\collections\form\HtmlForm;
19
use Ajax\semantic\components\validation\Rule;
20
use Ajax\php\ubiquity\JsUtils;
21
use Ubiquity\cache\CacheManager;
22
23
/**
24
 * Controller Auth
25
 *
26
 * @property \Ajax\php\ubiquity\JsUtils $jquery
27
 */
28
abstract class AuthController extends Controller {
29
	use AuthControllerCoreTrait,AuthControllerVariablesTrait,AuthControllerOverrideTrait,InsertJqueryTrait,Auth2FATrait,AuthAccountCreationTrait,AuthAccountRecoveryTrait;
2 ignored issues
show
Bug introduced by
The trait Ubiquity\controllers\aut...uthAccountCreationTrait requires the property $s which is not provided by Ubiquity\controllers\auth\AuthController.
Loading history...
Bug introduced by
The trait Ubiquity\controllers\aut...uthAccountRecoveryTrait requires the property $s which is not provided by Ubiquity\controllers\auth\AuthController.
Loading history...
30
31
	/**
32
	 *
33
	 * @var AuthFiles
34
	 */
35
	protected $authFiles;
36
	protected $_controller;
37
	protected $_action;
38
	protected $_actionParams;
39
	protected $_noAccessMsg;
40
	protected $_loginCaption;
41
	protected $_attemptsSessionKey = '_attempts';
42
	protected $_controllerInstance;
43
	protected $_compileJS = true;
44
	protected $_invalid=false;
45
46 1
	public function __construct($instance = null) {
47 1
		parent::__construct ();
48 1
		$this->_insertJquerySemantic ();
49 1
		$this->_controller = Startup::getController ();
50 1
		$this->_action = Startup::getAction ();
51 1
		$this->_actionParams = Startup::getActionParams ();
52 1
		$this->_noAccessMsg = new FlashMessage ( 'You are not authorized to access the page <b>{url}</b> !', 'Forbidden access', 'error', 'warning circle' );
53 1
		$this->_loginCaption = 'Log in';
54 1
		$this->_controllerInstance = $instance;
55 1
		if (isset ( $instance )){
56
			Startup::injectDependences ( $instance );
57
		}
58 1
		if($this->useAjax() && !URequest::isAjax()) {
59 1
			$this->_addAjaxBehavior($instance->jquery??$this->jquery);
60
		}
61
	}
62
63 1
	public function index() {
64 1
		if (($nbAttempsMax = $this->attemptsNumber ()) !== null) {
65
			$nb = USession::getTmp ( $this->_attemptsSessionKey, $nbAttempsMax );
66
			if ($nb <= 0) {
67
				$this->badLogin ();
68
				return;
69
			}
70
		}
71 1
		if($this->useAjax()){
72 1
			$this->_addFrmAjaxBehavior('frm-login');
73
		}
74 1
		$vData=[ 'action' => $this->getBaseUrl () . '/connect','loginInputName' => $this->_getLoginInputName (),'loginLabel' => $this->loginLabel (),'passwordInputName' => $this->_getPasswordInputName (),'passwordLabel' => $this->passwordLabel (),'rememberCaption' => $this->rememberCaption () ];
75 1
		$this->addAccountCreationViewData($vData,true);
76 1
		$this->authLoadView ( $this->_getFiles ()->getViewIndex (), $vData );
77
	}
78
79
	/**
80
	 *
81
	 * {@inheritdoc}
82
	 * @see \Ubiquity\controllers\Controller::isValid()
83
	 */
84 1
	public final function isValid($action) {
85 1
		return true;
86
	}
87
88
	/**
89
	 * Action called when the user does not have access rights to a requested resource
90
	 *
91
	 * @param array|string $urlParts
92
	 */
93 1
	public function noAccess($urlParts) {
94 1
		if (! \is_array ( $urlParts )) {
95
			$urlParts = \explode ( '.', $urlParts );
96
		}
97 1
		USession::set ( 'urlParts', $urlParts );
98 1
		$fMessage = $this->_noAccessMsg;
99 1
		$this->noAccessMessage ( $fMessage );
100 1
		$message = $this->fMessage ( $fMessage->parseContent ( [ 'url' => \implode ( '/', $urlParts ) ] ) );
101
		
102 1
		if (URequest::isAjax ()) {
103
			$this->jquery->get ( $this->_getBaseRoute () . '/info/f', '#_userInfo', [ 'historize' => false,'jqueryDone' => 'replaceWith','hasLoader' => false,'attr' => '' ] );
104
			$this->jquery->compile ( $this->view );
105
		}
106 1
		$vData=[ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ];
107 1
		$this->addAccountCreationViewData($vData);
108 1
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), $vData);
109
	}
110
111
	/**
112
	 * Override to implement the complete connection procedure
113
	 *
114
	 * @post
115
	 */
116
	#[\Ubiquity\attributes\items\router\Post]
117 1
	public function connect() {
118 1
		if (URequest::isPost ()) {
119 1
			if ($connected = $this->_connect ()) {
120 1
				if (isset ( $_POST ['ck-remember'] )) {
121
					$this->rememberMe ( $connected );
122
				}
123 1
				if (USession::exists ( $this->_attemptsSessionKey )) {
124
					USession::delete ( $this->_attemptsSessionKey );
125
				}
126 1
				if($this->has2FA($connected)){
127
					$this->initializeAuth();
128
					USession::set($this->_getUserSessionKey().'-2FA', $connected);
129
					$this->send2FACode();
130
					$this->confirm();
131
					$this->finalizeAuth();
132
				}else{
133 1
					$this->onConnect ( $connected );
134
				}
135
			} else {
136 1
				$this->_invalid=true;
137 1
				$this->initializeAuth();
138 1
				$this->onBadCreditentials ();
139 1
				$this->finalizeAuth();
140
			}
141
		}
142
	}
143
144
	/**
145
	 * Default Action for invalid creditentials
146
	 *
147
	 * @noRoute()
148
	 */
149
	#[\Ubiquity\attributes\items\router\NoRoute]
150 1
	public function badLogin() {
151 1
		$fMessage = new FlashMessage ( 'Invalid creditentials!', 'Connection problem', 'warning', 'warning circle' );
152 1
		$this->badLoginMessage ( $fMessage );
153 1
		$attemptsMessage = '';
154 1
		if (($nbAttempsMax = $this->attemptsNumber ()) !== null) {
155
			$nb = USession::getTmp ( $this->_attemptsSessionKey, $nbAttempsMax );
156
			$nb --;
157
			if ($nb < 0) {
158
				$nb = 0;
159
			}
160
			if ($nb == 0) {
161
				$fAttemptsNumberMessage = $this->noAttempts ();
162
			} else {
163
				$fAttemptsNumberMessage = new FlashMessage ( '<i class="ui warning icon"></i> You still have {_attemptsCount} attempts to log in.', null, 'bottom attached warning', '' );
164
			}
165
			USession::setTmp ( $this->_attemptsSessionKey, $nb, $this->attemptsTimeout () );
166
			$this->attemptsNumberMessage ( $fAttemptsNumberMessage, $nb );
167
			$fAttemptsNumberMessage->parseContent ( [ '_attemptsCount' => $nb,'_timer' => '<span id="timer"></span>' ] );
168
			$attemptsMessage = $this->fMessage ( $fAttemptsNumberMessage, 'timeout-message' );
169
			$fMessage->addType ( "attached" );
170
		}
171 1
		$message = $this->fMessage ( $fMessage, 'bad-login' ) . $attemptsMessage;
172 1
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), [ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ] );
173
	}
174
	
175
	/**
176
	 * Logout action
177
	 * Terminate the session and display a logout message
178
	 */
179 1
	public function terminate() {
180 1
		USession::terminate ();
181 1
		$fMessage = new FlashMessage ( 'You have been properly disconnected!', 'Logout', 'success', 'checkmark' );
182 1
		$this->terminateMessage ( $fMessage );
183 1
		$message = $this->fMessage ( $fMessage );
184 1
		$this->authLoadView ( $this->_getFiles ()->getViewNoAccess (), [ '_message' => $message,'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector (),'_loginCaption' => $this->_loginCaption ] );
185
	}
186
187
	public function _disConnected() {
188
		$fMessage = new FlashMessage ( 'You have been disconnected from the application!', 'Logout', '', 'sign out' );
189
		$this->disconnectedMessage ( $fMessage );
190
		$message = $this->fMessage ( $fMessage );
191
		$this->jquery->getOnClick ( '._signin', $this->getBaseUrl (), $this->_getBodySelector (), [ 'stopPropagation' => false,'preventDefault' => false ] );
192
		$this->jquery->execOn ( 'click', '._close', "window.open(window.location,'_self').close();" );
193
		return $this->jquery->renderView ( $this->_getFiles ()->getViewDisconnected (), [ "_title" => 'Session ended','_message' => $message ], true );
194
	}
195
196
	/**
197
	 * Action displaying the logged user information
198
	 * if _displayInfoAsString returns true, use _infoUser var in views to display user info
199
	 *
200
	 * @param null|boolean $force
201
	 * @return string|null
202
	 * @throws \Exception
203
	 */
204 1
	public function info($force = null) {
205 1
		if (isset ( $force )) {
206
			$displayInfoAsString = $force === true;
207
		} else {
208 1
			$displayInfoAsString = $this->_displayInfoAsString ();
209
		}
210 1
		return $this->loadView ( $this->_getFiles ()->getViewInfo (), [ 'connected' => USession::get ( $this->_getUserSessionKey () ),'authURL' => $this->getBaseUrl (),'bodySelector' => $this->_getBodySelector () ], $displayInfoAsString );
211
	}
212
	
213
	public function checkConnection() {
214
		UResponse::asJSON ();
215
		echo \json_encode(['valid'=> UString::getBooleanStr ( $this->_isValidUser () )]);
216
	}
217
218
	/**
219
	 * Sets the default noAccess message
220
	 * Default : "You are not authorized to access the page <b>{url}</b> !"
221
	 *
222
	 * @param string $content
223
	 * @param string $title
224
	 * @param string $type
225
	 * @param string $icon
226
	 */
227
	public function _setNoAccessMsg($content, $title = NULL, $type = NULL, $icon = null) {
228
		$this->_noAccessMsg->setValues ( $content, $title, $type, $icon );
229
	}
230
231
	/**
232
	 *
233
	 * @param string $_loginCaption
234
	 */
235
	public function _setLoginCaption($_loginCaption) {
236
		$this->_loginCaption = $_loginCaption;
237
	}
238
239
	/**
240
	 * Auto connect the user
241
	 */
242 1
	public function _autoConnect() {
243 1
		$cookie = $this->getCookieUser ();
244 1
		if (isset ( $cookie )) {
245
			$user = $this->fromCookie ( $cookie );
246
			if (isset ( $user )) {
247
				USession::set ( $this->_getUserSessionKey (), $user );
248
			}
249
		}
250
	}
251
252
	/**
253
	 * Deletes the cookie for auto connection and returns to index
254
	 */
255
	public function forgetConnection() {
256
		UCookie::delete ( $this->_getUserSessionKey () );
257
		$this->index ();
258
	}
259
260
	/**
261
	 *
262
	 * {@inheritdoc}
263
	 * @see \Ubiquity\controllers\ControllerBase::finalize()
264
	 */
265 1
	public function finalize() {
266 1
		if (! UResponse::isJSON ()) {
267 1
			if(Startup::getAction()!=='connect') {
268 1
				$this->finalizeAuth();
269
			}
270 1
			$this->jquery->execAtLast ( "if($('#_userInfo').length){\$('#_userInfo').replaceWith(" . \preg_replace ( "/$\R?^/m", "", Javascript::prep_element ( $this->info () ) ) . ");}" );
271 1
			if ($this->_compileJS) {
272 1
				echo $this->jquery->compile ();
273
			}
274
		}
275
	}
276
277 1
	protected function finalizeAuth() {
278 1
		if (!URequest::isAjax()) {
279 1
			$this->loadView('@activeTheme/main/vFooter.html');
280
		}
281
	}
282
283
	/**
284
	 *
285
	 * {@inheritdoc}
286
	 * @see \Ubiquity\controllers\ControllerBase::initialize()
287
	 */
288 1
	public function initialize() {
289 1
		if(Startup::getAction()!=='connect') {
290 1
			$this->initializeAuth();
291
		}
292
	}
293
294 1
	protected function initializeAuth() {
295 1
		if (!URequest::isAjax()) {
296 1
			$this->loadView('@activeTheme/main/vHeader.html');
297
		}
298
	}
299
300
	/**
301
	 *
302
	 * @param string $url
303
	 */
304 1
	public function _forward($url, $initialize = null, $finalize = null) {
305 1
		if (! isset ( $initialize )) {
306 1
			$initialize = (! isset ( $this->_controllerInstance ) || URequest::isAjax ());
307
		}
308 1
		if (! isset ( $finalize )) {
309 1
			$finalize = $initialize;
310
		}
311 1
		Startup::forward ( $url, $initialize, $finalize );
312
	}
313
	
314 1
	public function _addAjaxBehavior(JsUtils $jquery=null,$ajaxParameters=['hasLoader'=>'$(this).children(".button")','historize'=>false,'listenerOn'=>'body']){
315 1
		$jquery??=$this->jquery;
316 1
		$jquery->getHref('.ajax[data-target]','', $ajaxParameters);
317 1
		$jquery->postFormAction('.ui.form',$this->_getBodySelector(),$ajaxParameters);
318
	}
319
320 1
	public function _addFrmAjaxBehavior($id):HtmlForm{
321 1
		$frm=$this->jquery->semantic()->htmlForm($id);
322 1
		$frm->addExtraFieldRule($this->_getLoginInputName(),'empty');
323 1
		$frm->addExtraFieldRule($this->_getPasswordInputName(),'empty');
324 1
		$frm->setValidationParams(['inline'=>true,'on'=>'blur']);
325 1
		return $frm;
326
	}
327
}
328