Add filters as in the test system
[cacert-mgr.git] / manager / application / controllers / LoginController.php
1 <?php
2 /**
3 * @author markus
4 * $Id: LoginController.php 75 2010-02-25 14:40:10Z markus $
5 */
6
7 require_once('helpers/GetEnv.php');
8 require_once('config/Config.php');
9
10 class LoginController extends Zend_Controller_Action
11 {
12
13 public function init() {
14 /* Initialize action controller here */
15 $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV);
16
17 $db = Zend_Db::factory($config->ca_mgr->db->auth->pdo, $config->ca_mgr->db->auth);
18 Zend_Registry::set('auth_dbc', $db);
19 $db2 = Zend_Db::factory($config->ca_mgr->db->auth2->pdo, $config->ca_mgr->db->auth2);
20 Zend_Registry::set('auth2_dbc', $db2);
21 }
22
23 public function indexAction() {
24 $this->view->form = $this->getForm();
25 $this->render('index');
26 }
27
28 public function loginAction() {
29 $form = $this->getForm();
30 if ($form->isValid($_POST)) {
31 $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV);
32
33 $db = Zend_Registry::get('auth_dbc');
34 $db2 = Zend_Registry::get('auth2_dbc');
35
36 $auth = new Zend_Auth_Adapter_DbTable($db);
37
38 $auth->setTableName($config->ca_mgr->db->auth->tablename)
39 ->setIdentityColumn('email')
40 ->setCredentialColumn('password');
41
42 $auth->setIdentity( $this->getRequest()->getParam('login_name'))
43 ->setCredential( sha1($this->getRequest()->getParam('login_password')))
44 ->setCredentialTreatment('?');
45
46 $result = $auth->authenticate();
47
48 $code = $result->getCode();
49 switch ($code) {
50 case Zend_Auth_Result::FAILURE:
51 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE) to log in ' . $this->getRequest()->getParam('login_name'));
52 throw new Exception(__METHOD__ . ': unknown error');
53 case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
54 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND) to log in ' . $this->getRequest()->getParam('login_name'));
55 throw new Exception(__METHOD__ . ': ID unknown');
56 case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
57 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS) to log in ' . $this->getRequest()->getParam('login_name'));
58 throw new Exception(__METHOD__ . ': ID not unique');
59 case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
60 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID) to log in ' . $this->getRequest()->getParam('login_name'));
61 throw new Exception(__METHOD__ . ': ID unknown'); // to prevent brute force password attachs
62 case Zend_Auth_Result::FAILURE_UNCATEGORIZED:
63 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_UNCATEGORIZED) to log in ' . $this->getRequest()->getParam('login_name'));
64 throw new Exception(__METHOD__ . ': unknown error');
65 }
66
67 $this->getAuthDetailsIntoSession($auth, false);
68
69 Log::Log()->info(__METHOD__ . ' user logged in ' . $this->view->session->authdata['authed_username'] .
70 ' (' . $this->getRequest()->getParam('login_name') . ')');
71
72 #$this->_forward('index', 'index'); // only "soft" forward, we need to change the url in browser
73 $this->_redirect($this->view->url(array('controller' => 'index', 'action' => 'index'), 'default', true));
74
75 /*
76 $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
77 $viewRenderer->setRender('loginresult');
78 $this->view->request = $this->getRequest();
79 */
80 }
81 else {
82 $this->view->form = $form;
83 return $this->render('index');
84 }
85 }
86
87 public function crtAction() {
88 $ssl_client_s_dn = GetEnv::getEnvVar('SSL_CLIENT_S_DN');
89 $ssl_client_i_dn = GetEnv::getEnvVar('SSL_CLIENT_I_DN');
90
91 $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV);
92
93 $db = Zend_Registry::get('auth_dbc');
94 $db2 = Zend_Registry::get('auth2_dbc');
95
96 $auth = new Zend_Auth_Adapter_DbTable($db2);
97
98 $auth->setTableName($config->ca_mgr->db->auth2->tablename)
99 ->setIdentityColumn('user_client_crt_s_dn_i_dn')
100 ->setCredentialColumn('user_client_crt_s_dn_i_dn');
101
102 $auth->setIdentity( $ssl_client_s_dn . '//' . $ssl_client_i_dn)
103 ->setCredential($ssl_client_s_dn . '//' . $ssl_client_i_dn)
104 ->setCredentialTreatment('?');
105
106 $result = $auth->authenticate();
107
108 $code = $result->getCode();
109 switch ($code) {
110 case Zend_Auth_Result::FAILURE:
111 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
112 throw new Exception(__METHOD__ . ': unknown error');
113 case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
114 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
115 throw new Exception(__METHOD__ . ': ID unknown');
116 case Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS:
117 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
118 throw new Exception(__METHOD__ . ': ID not unique');
119 case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
120 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
121 throw new Exception(__METHOD__ . ': ID unknown'); // to prevent brute force password attachs
122 case Zend_Auth_Result::FAILURE_UNCATEGORIZED:
123 Log::Log()->info(__METHOD__ . ' user failed (Zend_Auth_Result::FAILURE_UNCATEGORIZED) to log in ' . $ssl_client_s_dn . '//' . $ssl_client_i_dn);
124 throw new Exception(__METHOD__ . ': unknown error');
125 }
126
127 $this->getAuthDetailsIntoSession($auth, true);
128
129 /*
130 $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
131 $viewRenderer->setRender('loginresult');
132 */
133
134 Log::Log()->info(__METHOD__ . ' user logged in ' . $this->view->session->authdata['authed_username'] .
135 ' (' . $ssl_client_s_dn . '//' . $ssl_client_i_dn . ')');
136
137 #$this->_forward('index', 'index'); // only "soft" forward, we need to change the url in browser
138 $this->_redirect($this->view->url(array('controller' => 'index', 'action' => 'index'), 'default', true));
139 }
140
141 /**
142 * get user data from Zend_Auth result and store data in session
143 * @param Zend_Auth_Result $auth
144 */
145 protected function getAuthDetailsIntoSession($auth, $crt) {
146 $session = Zend_Registry::get('session');
147
148 $db = Zend_Registry::get('auth_dbc');
149 $db2 = Zend_Registry::get('auth2_dbc');
150
151 /**
152 * non existent in our case, look up a 2nd table (ca_mgr.system_user by login name (email)) and
153 * get id from there, defaulting to User (1) when no db entry exists
154 */
155 $auth_res = $auth->getResultRowObject();
156
157 if (!isset($auth_res->system_role_id) || $auth_res->system_role_id == 0) {
158 $res = $db2->query('select * from system_user where login=?', array($auth_res->email));
159 if ($res->rowCount() > 0) {
160 $res_ar = $res->fetch();
161 $system_roles_id = $res_ar['system_role_id'];
162 }
163 else {
164 // no extra user info in manager database, assume standard user
165 $system_roles_id = 1;
166 }
167 }
168 else
169 $system_roles_id = $auth_res->system_role_id;
170
171 $session->authdata['authed'] = true;
172 $session->authdata['authed_id'] = $auth_res->id;
173 if (!isset($auth_res->fname) || !isset($auth_res->lname)) {
174 $res = $db->query('select * from users where email=?', array($auth_res->login));
175 $res_ar = $res->fetch();
176 $session->authdata['authed_username'] = 'crt' . $res_ar['login'];
177 $session->authdata['authed_fname'] = $res_ar['fname'];
178 $session->authdata['authed_lname'] = $res_ar['lname'];
179 }
180 else {
181 $session->authdata['authed_username'] = $auth_res->email;
182 $session->authdata['authed_fname'] = $auth_res->fname;
183 $session->authdata['authed_lname'] = $auth_res->lname;
184 }
185 $session->authdata['authed_by_crt'] = $crt;
186 $session->authdata['authed_by_cli'] = true;
187
188 $res = $db2->query('select * from system_role where id=?', array($system_roles_id));
189 $res_ar = $res->fetch();
190 $session->authdata['authed_role'] = $res_ar['role'];
191
192 $acl = $this->makeAcl($db2);
193
194 $session->authdata['authed_permissions'] = $acl;
195
196 /* test cases
197 Log::Log()->debug(($acl->isAllowed('User', 'Administration', 'view') == true)?'true':'false');
198 Log::Log()->debug(($acl->isAllowed('User', 'Administration', 'edit') == true)?'true':'false');
199 Log::Log()->debug(($acl->isAllowed('User', 'Account', 'view') == true)?'true':'false');
200 Log::Log()->debug(($acl->isAllowed('User', 'Account', 'edit') == true)?'true':'false');
201 Log::Log()->debug(($acl->isAllowed('Admin', 'Administration', 'view') == true)?'true':'false');
202 Log::Log()->debug(($acl->isAllowed('Admin', 'Account', 'view') == true)?'true':'false');
203 */
204
205 $this->view->session = $session;
206 }
207
208 /**
209 * build login form and return to requesting method
210 * @return Zend_Form
211 */
212 protected function getForm() {
213 $form = new Zend_Form();
214 $form->setAction('/login/login')
215 ->setMethod('post');
216 #$form->setAttrib('id', 'loginform');
217 $al = new Zend_Validate_Alnum();
218 $al->setDefaultTranslator(I18n::getTranslate());
219 $al->setDisableTranslator(false);
220 $username = new Zend_Form_Element_Text('login_name');
221 $username->setRequired(true)
222 ->setLabel(I18n::_('User Name'))
223 ->addFilter(new Zend_Filter_StringTrim())
224 ->addFilter(new Zend_Filter_StripTags());
225 $password = new Zend_Form_Element_Password('login_password');
226 $password->setRequired(true)
227 ->setLabel(I18n::_('Password'))
228 ->addFilter(new Zend_Filter_StringTrim());
229 $submit = new Zend_Form_Element_Submit('submit');
230 $submit->setLabel(I18n::_('Login'));
231 $form->addElement($username)
232 ->addElement($password)
233 ->addElement($submit);
234
235 return $form;
236 }
237
238 /**
239 * get roles and resources from db, build Zend_Acl structure and add permissions
240 * @param Zend_Db $db
241 */
242 protected function makeAcl($db) {
243 $acl = new Zend_Acl();
244
245 $res = $db->fetchAll('select * from system_role');
246 foreach ($res as $obj) {
247 if ($obj['inherit_role'] != '') {
248 if ($acl->hasRole($obj['inherit_role'])) {
249 $acl->addRole(new Zend_Acl_Role($obj['role']), $obj['inherit_role']);
250 }
251 else {
252 /**
253 * @todo very simply system to order roles, add role before inherited role
254 */
255 $res[] = $obj;
256 continue;
257 }
258 }
259 else {
260 $acl->addRole(new Zend_Acl_Role($obj['role']));
261 }
262 }
263
264 $res = $db->fetchAll('select * from system_resource');
265 foreach ($res as $obj) {
266 $acl->addResource(new Zend_Acl_Resource($obj['resource']));
267 }
268
269 $res = $db->fetchAll('select r.role as role, rs.resource as resource, permission, privilege '.
270 'from system_role as r join system_role_has_system_resource as m on ' .
271 '(r.id = m.system_role_id) join system_resource as rs on (m.system_resource_id = rs.id)');
272
273 foreach ($res as $obj) {
274 $privilege = explode(',', $obj['privilege']);
275 if ($obj['permission'] == 'allow') {
276 $acl->allow($obj['role'], $obj['resource'], $privilege);
277 }
278 else {
279 $acl->deny($obj['role'], $obj['resource'], $privilege);
280 }
281 }
282
283 return $acl;
284 }
285 }