+ }
+ $sr = ldap_search($ds, "dc=cs,dc=curs,dc=pub,dc=ro", "(uid=" . $username . ")");
+ if (ldap_count_entries($ds, $sr) > 1)
+ die("Multiple entries with the same uid in LDAP database??");
+ if (ldap_count_entries($ds, $sr) < 1) {
+ ldap_close($ds);
+ return FALSE;
+ }
+
+ $info = ldap_get_entries($ds, $sr);
+ $dn = $info[0]["dn"];
+ ldap_close($ds);
+
+ // Second connection: connect with user's credentials.
+ $ds = ldap_connect($this->config->item('ldap_server')) or die("Can't connect to ldap server\n");
+ if (!@ldap_bind($ds, $dn, $password) or $password == '') {
+ ldap_close($ds);
+ return FALSE;
+ }
+
+ // Verifify if DN belongs to the requested OU.
+ $info[0]['ou_ok'] = $this->ldap_dn_belongs_ou( $dn, $this->config->item('ldap_req_ou') );
+
+ // Set authentication source.
+ $info[0]['auth_src'] = 'ldap_first_time';
+
+ return $info[0];
+ }
+
+ /**
+ * Verify if a user belongs to a group.
+ *
+ * @param string $dn = "ou=Student,ou=People..."
+ * @param array $ou = array ("Student", etc
+ * @return TRUE or FALSE
+ * @author Răzvan Herișanu, Răzvan Deaconescu, Călin-Andrei Burloiu
+ */
+ public function ldap_dn_belongs_ou($dn, $ou)
+ {
+ if (!is_array($ou))
+ $ou = array ($ou);
+
+ $founded = FALSE;
+ $words = explode(',', $dn);
+ foreach ($words as $c) {
+ $parts = explode("=", $c);
+ $key = $parts[0];
+ $value = $parts[1];
+
+ if (strtolower($key) == "ou" && in_array($value, $ou) )
+ $founded = TRUE;
+ }
+
+ return $founded;
+ }
+
+ /**
+ * Adds a new user to DB.
+ * Do not add join_date and last_login column, they will be automatically
+ * added.
+ *
+ * @param array $data corresponds to DB columns
+ */
+ public function register($data)
+ {
+ $this->load->helper('array');
+
+ // TODO verify mandatory data existance
+
+ // Process data.
+ if (isset($data['password']))
+ $data['password'] = sha1($data['password']);
+ // TODO picture data: save, convert, make it thumbnail
+
+ $cols = '';
+ $vals = '';
+ foreach ($data as $col=> $val)
+ {
+ $cols .= "$col, ";
+ if (is_int($val))
+ $vals .= "$val, ";
+ else
+ $vals .= "'$val', ";
+ }
+ $cols = substr($cols, 0, -2);
+ $vals = substr($vals, 0, -2);
+
+ $query = $this->db->query("INSERT INTO `users`
+ ($cols, registration_date, last_login)
+ VALUES ($vals, utc_timestamp(), utc_timestamp())");
+
+ if ($query === FALSE)
+ return FALSE;
+
+ // If the registered with internal authentication it needs to activate
+ // the account.
+ $activation_code = Users_model::gen_activation_code();
+ $user_id = $this->get_user_id($data['username']);
+ $query = $this->db->query("INSERT INTO `users_unactivated`
+ (user_id, activation_code)
+ VALUES ($user_id, '$activation_code')");
+
+ // TODO exception on failure
+ return $query;
+ }
+
+ public function get_user_id($username)
+ {
+ $query = $this->db->query("SELECT id FROM `users`
+ WHERE username = '$username'");
+
+ if ($query->num_rows() === 0)
+ return FALSE;
+
+ return $query->row()->id;
+ }
+
+ // TODO cleanup account activation
+ public function cleanup_account_activation()
+ {
+
+ }
+
+ /**
+ * Activated an account for an user having $user_id with $activation_code.
+ *
+ * @param int $user_id
+ * @param string $activation_code hexa 16 characters string
+ * @return returns TRUE if activation was successful and FALSE otherwise
+ */
+ public function activate_account($user_id, $activation_code)
+ {
+ $query = $this->db->query("SELECT * FROM `users_unactivated`
+ WHERE user_id = $user_id
+ AND activation_code = '$activation_code'");
+
+ if ($query->num_rows() === 0)
+ return FALSE;
+
+ $this->db->query("DELETE FROM `users_unactivated`
+ WHERE user_id = $user_id");
+
+ return TRUE;
+ }
+
+ /**
+ * Returns data from `users` table. If $user is int it is used as an
+ * id, if it is string it is used as an username.
+ *
+ * @param mixed $user
+ */
+ public function get_userdata($user)
+ {
+ if (is_int($user))
+ $cond = "id = $user";
+ else
+ $cond = "username = '$user'";
+
+ $query = $this->db->query("SELECT * from `users`
+ WHERE $cond");
+
+ if ($query->num_rows() === 0)
+ return FALSE;
+