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