1: <?php
2:
3: namespace Alpha\Controller;
4:
5: use Alpha\Util\Logging\Logger;
6: use Alpha\Util\Config\ConfigProvider;
7: use Alpha\Util\Http\Request;
8: use Alpha\Util\Http\Response;
9: use Alpha\Util\Http\Session\SessionProviderFactory;
10: use Alpha\View\View;
11: use Alpha\View\PersonView;
12: use Alpha\Model\Person;
13: use Alpha\Model\ActiveRecord;
14: use Alpha\Exception\IllegalArguementException;
15: use Alpha\Exception\SecurityException;
16: use Alpha\Exception\ValidationException;
17: use Alpha\Exception\RecordNotFoundException;
18: use Alpha\Controller\Front\FrontController;
19:
20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
62: class LoginController extends Controller implements ControllerInterface
63: {
64: 65: 66: 67: 68: 69: 70:
71: protected $personObject;
72:
73: 74: 75: 76: 77: 78: 79:
80: private $personView;
81:
82: 83: 84: 85: 86: 87: 88:
89: private static $logger = null;
90:
91: 92: 93: 94: 95:
96: public function __construct()
97: {
98: self::$logger = new Logger('LoginController');
99: self::$logger->debug('>>__construct()');
100:
101: $config = ConfigProvider::getInstance();
102:
103:
104: parent::__construct('Public');
105:
106: $this->personObject = new Person();
107: $this->personView = View::getInstance($this->personObject);
108: $this->setRecord($this->personObject);
109:
110:
111: $this->setTitle('Login to '.$config->get('app.title'));
112: $this->setDescription('Login page.');
113: $this->setKeywords('login,logon');
114:
115: self::$logger->debug('<<__construct');
116: }
117:
118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128:
129: public function doGET($request)
130: {
131: self::$logger->debug('>>doGET($request=['.var_export($request, true).'])');
132:
133: $params = $request->getParams();
134:
135: if (!is_array($params)) {
136: throw new IllegalArguementException('Bad $params ['.var_export($params, true).'] passed to doGET method!');
137: }
138:
139: $body = View::displayPageHead($this);
140:
141: if (isset($params['reset'])) {
142: $body .= $this->personView->displayResetForm();
143: } else {
144: $body .= $this->personView->displayLoginForm();
145: }
146:
147: $body .= View::displayPageFoot($this);
148:
149: self::$logger->debug('<<doGET');
150:
151: return new Response(200, $body, array('Content-Type' => 'text/html'));
152: }
153:
154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164:
165: public function doPOST($request)
166: {
167: self::$logger->debug('>>doPOST($request=['.var_export($request, true).'])');
168:
169: $params = $request->getParams();
170:
171: if (!is_array($params)) {
172: throw new IllegalArguementException('Bad $params ['.var_export($params, true).'] passed to doPOST method!');
173: }
174:
175: $config = ConfigProvider::getInstance();
176:
177: $body = '';
178:
179: try {
180:
181: if (!$this->checkSecurityFields()) {
182: throw new SecurityException('This page cannot accept post data from remote servers!');
183: }
184:
185: if (isset($params['loginBut'])) {
186:
187: if (!ActiveRecord::isInstalled()) {
188: if ($params['email'] == $config->get('app.install.username') && password_verify($params['password'], password_hash($config->get('app.install.password'), PASSWORD_DEFAULT, ['cost' => 12]))) {
189: self::$logger->info('Logging in ['.$params['email'].'] at ['.date('Y-m-d H:i:s').']');
190: $admin = new Person();
191: $admin->set('displayName', 'Admin');
192: $admin->set('email', $params['email']);
193: $admin->set('password', password_hash($params['password'], PASSWORD_DEFAULT, ['cost' => 12]));
194: $admin->set('OID', '00000000001');
195:
196: $sessionProvider = $config->get('session.provider.name');
197: $session = SessionProviderFactory::getInstance($sessionProvider);
198: $session->set('currentUser', $admin);
199:
200: $response = new Response(301);
201: if ($this->getNextJob() != '') {
202: $response->redirect(FrontController::generateSecureURL('act='.$this->getNextJob()));
203: $this->clearUnitOfWorkAttributes();
204: } else {
205: $response->redirect(FrontController::generateSecureURL('act=InstallController'));
206: }
207:
208: return $response;
209: } else {
210: throw new ValidationException('Failed to login user '.$params['email'].', the password is incorrect!');
211: }
212: } else {
213:
214: $this->personObject->loadByAttribute('email', $params['email'], true);
215:
216: ActiveRecord::disconnect();
217:
218:
219: if (!$this->personObject->isTransient() && $this->personObject->get('state') == 'Disabled') {
220: throw new SecurityException('Failed to login user '.$params['email'].', that account has been disabled!');
221: }
222:
223:
224: return $this->doLoginAndRedirect($params['password']);
225: }
226:
227: $body .= View::displayPageHead($this);
228:
229: $body .= $this->personView->displayLoginForm();
230: }
231:
232: if (isset($params['resetBut'])) {
233:
234: $this->personObject->loadByAttribute('email', $params['email']);
235:
236: ActiveRecord::disconnect();
237:
238:
239: $newPassword = $this->personObject->generatePassword();
240:
241:
242: $this->personObject->set('password', password_hash($newPassword, PASSWORD_DEFAULT, ['cost' => 12]));
243: $this->personObject->save();
244:
245: $message = 'The password for your account has been reset to '.$newPassword.' as you requested. You can now login to the site using your '.
246: 'e-mail address and this new password as before.';
247: $subject = 'Password change request';
248:
249: $this->personObject->sendMail($message, $subject);
250:
251: $body .= View::displayUpdateMessage('The password for the user <strong>'.$params['email'].'</strong> has been reset, and the new password '.
252: 'has been sent to that e-mail address.');
253: $body .= '<a href="'.$config->get('app.url').'">Home Page</a>';
254: }
255: } catch (ValidationException $e) {
256: $body .= View::displayPageHead($this);
257:
258: $body .= View::displayErrorMessage($e->getMessage());
259:
260: if (isset($params['reset'])) {
261: $body .= $this->personView->displayResetForm();
262: } else {
263: $body .= $this->personView->displayLoginForm();
264: }
265:
266: self::$logger->warn($e->getMessage());
267: } catch (SecurityException $e) {
268: $body .= View::displayPageHead($this);
269:
270: $body .= View::displayErrorMessage($e->getMessage());
271:
272: self::$logger->warn($e->getMessage());
273: } catch (RecordNotFoundException $e) {
274: $body .= View::displayPageHead($this);
275:
276: $body .= View::displayErrorMessage('Failed to find the user \''.$params['email'].'\'');
277:
278: if (isset($params['reset'])) {
279: $body .= $this->personView->displayResetForm();
280: } else {
281: $body .= $this->personView->displayLoginForm();
282: }
283:
284: self::$logger->warn($e->getMessage());
285: }
286:
287: $body .= View::displayPageFoot($this);
288:
289: self::$logger->debug('<<doPOST');
290:
291: return new Response(200, $body, array('Content-Type' => 'text/html'));
292: }
293:
294: 295: 296: 297: 298: 299: 300: 301: 302: 303: 304:
305: protected function doLoginAndRedirect($password)
306: {
307: self::$logger->debug('>>doLoginAndRedirect(password=['.$password.'])');
308:
309: $config = ConfigProvider::getInstance();
310:
311: if (!$this->personObject->isTransient() && $this->personObject->get('state') == 'Active') {
312: if (password_verify($password, $this->personObject->get('password'))) {
313: $sessionProvider = $config->get('session.provider.name');
314: $session = SessionProviderFactory::getInstance($sessionProvider);
315: $session->set('currentUser', $this->personObject);
316:
317: self::$logger->debug('Logging in ['.$this->personObject->get('email').'] at ['.date('Y-m-d H:i:s').']');
318: self::$logger->action('Login');
319:
320: $response = new Response(301);
321: if ($this->getNextJob() != '') {
322: $response->redirect(FrontController::generateSecureURL('act='.$this->getNextJob()));
323: $this->clearUnitOfWorkAttributes();
324: } else {
325: $response->redirect($config->get('app.url'));
326: }
327:
328: return $response;
329: } else {
330: throw new ValidationException('Failed to login user '.$this->personObject->get('email').', the password is incorrect!');
331: self::$logger->debug('<<doLoginAndRedirect');
332: }
333: }
334: }
335:
336: 337: 338: 339: 340: 341: 342:
343: public function ()
344: {
345: $config = ConfigProvider::getInstance();
346:
347: return '<p><em>Version '.$config->get('app.version').'</em></p>';
348: }
349: }
350: