Test Failed
Push — master ( 8ca2f4...a87d59 )
by Jean-Christophe
22:35
created

AuthController::_init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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