2011-08-18 01:31:15 +01:00
|
|
|
<?php
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
/* user_model.php
|
|
|
|
|
*
|
|
|
|
|
* This model implements user authentication and authorization
|
|
|
|
|
*
|
|
|
|
|
*/
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
|
2011-08-18 01:31:15 +01:00
|
|
|
// Uses 'phpass' from http://www.openwall.com/phpass/ to implement password hashing
|
2017-11-07 00:45:06 +00:00
|
|
|
// TODO migration away from this?
|
|
|
|
|
//require_once('application/third_party/PasswordHash.php');
|
2011-08-18 01:31:15 +01:00
|
|
|
|
|
|
|
|
class User_Model extends CI_Model {
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: object get($username)
|
2011-08-18 01:31:15 +01:00
|
|
|
// Retrieve a user
|
|
|
|
|
function get($username) {
|
2019-10-05 19:35:55 +01:00
|
|
|
// Clean ID
|
|
|
|
|
$clean_username = $this->security->xss_clean($username);
|
|
|
|
|
|
|
|
|
|
$this->db->where('user_name', $clean_username);
|
2011-08-18 01:31:15 +01:00
|
|
|
$r = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
return $r;
|
2021-02-26 10:37:43 +01:00
|
|
|
}
|
2011-08-18 01:31:15 +01:00
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: object get_by_id($id)
|
|
|
|
|
// Retrieve a user by user ID
|
2011-08-18 01:31:15 +01:00
|
|
|
function get_by_id($id) {
|
2019-10-05 19:35:55 +01:00
|
|
|
// Clean ID
|
|
|
|
|
$clean_id = $this->security->xss_clean($id);
|
|
|
|
|
|
|
|
|
|
$this->db->where('user_id', $clean_id);
|
2011-08-18 01:31:15 +01:00
|
|
|
$r = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
return $r;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-06 16:55:30 +01:00
|
|
|
// FUNCTION: object get_all_lotw_users
|
|
|
|
|
// Returns all users with lotw details
|
|
|
|
|
function get_all_lotw_users() {
|
|
|
|
|
$this->db->where('user_lotw_name !=', null);
|
2020-09-08 00:30:16 +01:00
|
|
|
$this->db->where('user_lotw_name !=', "");
|
2020-09-06 16:55:30 +01:00
|
|
|
$r = $this->db->get($this->config->item('auth_table'));
|
2011-08-18 01:31:15 +01:00
|
|
|
return $r;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-19 17:13:26 +01:00
|
|
|
// FUNCTION: object get_by_email($email)
|
|
|
|
|
// Retrieve a user by email address
|
|
|
|
|
function get_by_email($email) {
|
2019-10-05 19:35:55 +01:00
|
|
|
|
|
|
|
|
$clean_email = $this->security->xss_clean($email);
|
|
|
|
|
|
|
|
|
|
$this->db->where('user_email', $clean_email);
|
2011-08-19 17:13:26 +01:00
|
|
|
$r = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
return $r;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-19 15:37:34 +00:00
|
|
|
// FUNCTION: object get_by_callsign($callsign)
|
|
|
|
|
// Retrieve a user by callsign (case-insensitive)
|
|
|
|
|
function get_by_callsign($callsign) {
|
|
|
|
|
|
|
|
|
|
$clean_callsign = $this->security->xss_clean($callsign);
|
|
|
|
|
|
|
|
|
|
$this->db->where('UPPER(user_callsign)', strtoupper($clean_callsign));
|
|
|
|
|
$r = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
return $r;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-18 15:29:22 +00:00
|
|
|
/*
|
|
|
|
|
* Function: check_email_address
|
2023-08-02 06:34:12 +00:00
|
|
|
*
|
2022-01-18 15:29:22 +00:00
|
|
|
* Checks if an email address is already in use
|
2023-08-02 06:34:12 +00:00
|
|
|
*
|
2022-01-18 15:29:22 +00:00
|
|
|
* @param string $email
|
|
|
|
|
*/
|
|
|
|
|
function check_email_address($email) {
|
|
|
|
|
|
|
|
|
|
$clean_email = $this->security->xss_clean($email);
|
|
|
|
|
|
|
|
|
|
$this->db->where('user_email', $clean_email);
|
|
|
|
|
$query = $this->db->get($this->config->item('auth_table'));
|
2023-08-02 06:34:12 +00:00
|
|
|
|
2022-01-18 15:29:22 +00:00
|
|
|
if ($query->num_rows() > 0) {
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-21 12:12:21 +01:00
|
|
|
function get_user_email_by_id($id) {
|
|
|
|
|
|
|
|
|
|
$clean_id = $this->security->xss_clean($id);
|
|
|
|
|
|
|
|
|
|
$this->db->where('user_id', $clean_id);
|
|
|
|
|
$query = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
|
|
|
|
|
$r = $query->row();
|
|
|
|
|
return $r->user_email;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-07 16:30:40 +00:00
|
|
|
function hasQrzKey($user_id) {
|
Sanitize IDs and migrate SQL to Query Builder
Replace ad-hoc xss_clean calls with explicit casting and stronger type checks for ID/parameter handling, and convert many raw SQL strings to CodeIgniter Query Builder usage. Added normalize_location_ids helpers (Activators_model, Oqrs_model) to safely parse location lists and used where_in/parameter binding/escaping to avoid injection and improve maintainability. Also adjusted session user_id handling, improved LIKE/DATE/TIMEDIFF usage, and tightened several model/controller methods (Labels, Activators, Bands, Contesting, Labels_model, Modes, Oqrs_model, Qsl_model, Setup_model, Sstv_model, User_model) for safer, clearer DB queries and inputs.
2026-06-24 22:15:31 +01:00
|
|
|
$user_id = (int) $user_id;
|
2023-12-07 16:30:40 +00:00
|
|
|
$this->db->where('station_profile.qrzapikey is not null');
|
2023-12-14 16:08:17 +01:00
|
|
|
$this->db->where('station_profile.qrzapikey != ""');
|
Sanitize IDs and migrate SQL to Query Builder
Replace ad-hoc xss_clean calls with explicit casting and stronger type checks for ID/parameter handling, and convert many raw SQL strings to CodeIgniter Query Builder usage. Added normalize_location_ids helpers (Activators_model, Oqrs_model) to safely parse location lists and used where_in/parameter binding/escaping to avoid injection and improve maintainability. Also adjusted session user_id handling, improved LIKE/DATE/TIMEDIFF usage, and tightened several model/controller methods (Labels, Activators, Bands, Contesting, Labels_model, Modes, Oqrs_model, Qsl_model, Setup_model, Sstv_model, User_model) for safer, clearer DB queries and inputs.
2026-06-24 22:15:31 +01:00
|
|
|
$this->db->join('station_profile', 'station_profile.user_id = '.$this->config->item('auth_table').'.user_id');
|
|
|
|
|
$this->db->where('station_profile.user_id', $user_id);
|
2023-12-07 16:30:40 +00:00
|
|
|
$query = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
|
|
|
|
|
$ret = $query->row();
|
2023-12-13 12:10:20 +00:00
|
|
|
if ($ret->user_email ?? '' != '') {
|
2023-12-13 12:02:20 +00:00
|
|
|
return $ret->user_email;
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
2023-12-07 16:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
2023-04-25 14:00:30 +02:00
|
|
|
function get_email_address($station_id) {
|
Sanitize IDs and migrate SQL to Query Builder
Replace ad-hoc xss_clean calls with explicit casting and stronger type checks for ID/parameter handling, and convert many raw SQL strings to CodeIgniter Query Builder usage. Added normalize_location_ids helpers (Activators_model, Oqrs_model) to safely parse location lists and used where_in/parameter binding/escaping to avoid injection and improve maintainability. Also adjusted session user_id handling, improved LIKE/DATE/TIMEDIFF usage, and tightened several model/controller methods (Labels, Activators, Bands, Contesting, Labels_model, Modes, Oqrs_model, Qsl_model, Setup_model, Sstv_model, User_model) for safer, clearer DB queries and inputs.
2026-06-24 22:15:31 +01:00
|
|
|
$this->db->where('station_id', (int) $station_id);
|
2023-04-25 14:00:30 +02:00
|
|
|
$this->db->join('station_profile', 'station_profile.user_id = '.$this->config->item('auth_table').'.user_id');
|
2022-11-15 18:29:33 +01:00
|
|
|
$query = $this->db->get($this->config->item('auth_table'));
|
2023-08-02 06:34:12 +00:00
|
|
|
|
2022-11-15 18:29:33 +01:00
|
|
|
$ret = $query->row();
|
|
|
|
|
return $ret->user_email;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool exists($username)
|
|
|
|
|
// Check if a user exists (by username)
|
2011-08-18 01:31:15 +01:00
|
|
|
function exists($username) {
|
2019-10-05 19:35:55 +01:00
|
|
|
$clean_username = $this->security->xss_clean($username);
|
|
|
|
|
if($this->get($clean_username)->num_rows() == 0) {
|
2011-08-18 01:31:15 +01:00
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-19 17:13:26 +01:00
|
|
|
// FUNCTION: bool exists_by_id($id)
|
|
|
|
|
// Check if a user exists (by user ID)
|
|
|
|
|
function exists_by_id($id) {
|
2019-10-05 19:35:55 +01:00
|
|
|
$clean_id = $this->security->xss_clean($id);
|
|
|
|
|
|
|
|
|
|
if($this->get_by_id($clean_id)->num_rows() == 0) {
|
2011-08-19 17:13:26 +01:00
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUNCTION: bool exists_by_email($email)
|
|
|
|
|
// Check if a user exists (by email address)
|
|
|
|
|
function exists_by_email($email) {
|
2017-11-30 19:01:11 -07:00
|
|
|
if($this->get_by_email($email)->num_rows() == 0) {
|
2011-08-19 17:13:26 +01:00
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 14:22:02 +00:00
|
|
|
// FUNCTION: bool exists_by_callsign($callsign, $exclude_user_id = NULL)
|
|
|
|
|
// Check if a user exists (by callsign), optionally excluding one user ID
|
|
|
|
|
function exists_by_callsign($callsign, $exclude_user_id = NULL) {
|
|
|
|
|
$clean_callsign = $this->security->xss_clean($callsign);
|
|
|
|
|
|
|
|
|
|
$this->db->where('UPPER(user_callsign)', strtoupper($clean_callsign));
|
|
|
|
|
if ($exclude_user_id !== NULL && $exclude_user_id !== '') {
|
|
|
|
|
$this->db->where('user_id !=', $this->security->xss_clean($exclude_user_id));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$query = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
|
|
|
|
|
if($query->num_rows() == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function count_admin_users() {
|
|
|
|
|
$this->db->where('user_type', 99);
|
|
|
|
|
return $this->db->count_all_results($this->config->item('auth_table'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function would_remove_last_admin($user_id, $new_user_type) {
|
|
|
|
|
if ((string) $new_user_type === '99') {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$user = $this->get_by_id($user_id);
|
|
|
|
|
if ($user->num_rows() === 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((int) $user->row()->user_type !== 99) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->count_admin_users() <= 1;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool add($username, $password, $email, $type)
|
|
|
|
|
// Add a user
|
2021-05-07 08:03:25 +02:00
|
|
|
function add($username, $password, $email, $type, $firstname, $lastname, $callsign, $locator, $timezone,
|
2022-10-19 16:27:26 +02:00
|
|
|
$measurement, $user_date_format, $user_stylesheet, $user_qth_lookup, $user_sota_lookup, $user_wwff_lookup,
|
2023-05-01 21:14:30 +02:00
|
|
|
$user_pota_lookup, $user_show_notes, $user_column1, $user_column2, $user_column3, $user_column4, $user_column5,
|
2023-07-07 16:04:19 +02:00
|
|
|
$user_show_profile_image, $user_previous_qsl_type, $user_amsat_status_upload, $user_mastodon_url,
|
2024-03-09 08:49:12 +01:00
|
|
|
$user_default_band, $user_default_confirmation, $user_qso_end_times, $user_quicklog, $user_quicklog_enter,
|
2026-05-16 13:44:09 +01:00
|
|
|
$language, $user_hamsat_key, $user_hamsat_workable_only, $callbook_type, $callbook_username, $callbook_password,
|
|
|
|
|
$user_winkey, $user_winkey_websocket, $user_remote_operation) {
|
2011-08-19 17:13:26 +01:00
|
|
|
// Check that the user isn't already used
|
2011-08-18 01:31:15 +01:00
|
|
|
if(!$this->exists($username)) {
|
|
|
|
|
$data = array(
|
2019-10-05 22:16:58 +01:00
|
|
|
'user_name' => xss_clean($username),
|
2011-08-18 01:31:15 +01:00
|
|
|
'user_password' => $this->_hash($password),
|
2019-10-05 22:16:58 +01:00
|
|
|
'user_email' => xss_clean($email),
|
|
|
|
|
'user_type' => xss_clean($type),
|
2025-11-24 14:22:34 +00:00
|
|
|
'user_firstname' => xss_clean($firstname),
|
|
|
|
|
'user_lastname' => xss_clean($lastname),
|
|
|
|
|
'user_callsign' => strtoupper(xss_clean($callsign)),
|
|
|
|
|
'user_locator' => xss_clean($locator),
|
2025-12-02 18:10:37 +00:00
|
|
|
'user_timezone' => (int)$timezone,
|
2020-09-16 20:54:26 +01:00
|
|
|
'user_measurement_base' => xss_clean($measurement),
|
|
|
|
|
'user_date_format' => xss_clean($user_date_format),
|
2020-09-23 10:59:49 +02:00
|
|
|
'user_stylesheet' => xss_clean($user_stylesheet),
|
2025-12-02 18:10:37 +00:00
|
|
|
'user_qth_lookup' => (int)$user_qth_lookup,
|
|
|
|
|
'user_sota_lookup' => (int)$user_sota_lookup,
|
|
|
|
|
'user_wwff_lookup' => (int)$user_wwff_lookup,
|
|
|
|
|
'user_pota_lookup' => (int)$user_pota_lookup,
|
|
|
|
|
'user_show_notes' => (int)$user_show_notes,
|
2021-05-05 17:52:42 +02:00
|
|
|
'user_column1' => xss_clean($user_column1),
|
|
|
|
|
'user_column2' => xss_clean($user_column2),
|
|
|
|
|
'user_column3' => xss_clean($user_column3),
|
|
|
|
|
'user_column4' => xss_clean($user_column4),
|
2021-05-07 08:03:25 +02:00
|
|
|
'user_column5' => xss_clean($user_column5),
|
2025-12-02 18:10:37 +00:00
|
|
|
'user_show_profile_image' => (int)$user_show_profile_image,
|
|
|
|
|
'user_previous_qsl_type' => (int)$user_previous_qsl_type,
|
|
|
|
|
'user_amsat_status_upload' => (int)$user_amsat_status_upload,
|
2023-07-06 08:17:20 +00:00
|
|
|
'user_mastodon_url' => xss_clean($user_mastodon_url),
|
2023-10-16 22:39:33 +02:00
|
|
|
'user_default_band' => xss_clean($user_default_band),
|
|
|
|
|
'user_default_confirmation' => xss_clean($user_default_confirmation),
|
2025-12-02 18:10:37 +00:00
|
|
|
'user_qso_end_times' => (int)$user_qso_end_times,
|
|
|
|
|
'user_quicklog' => (int)$user_quicklog,
|
2023-11-05 12:29:59 +01:00
|
|
|
'user_quicklog_enter' => xss_clean($user_quicklog_enter),
|
2024-04-10 14:51:10 +01:00
|
|
|
'language' => xss_clean($language),
|
2026-05-16 13:44:09 +01:00
|
|
|
'winkey' => (int)$user_winkey,
|
|
|
|
|
'winkey_websocket' => (int)$user_winkey_websocket,
|
|
|
|
|
'remote_operation' => (int)$user_remote_operation,
|
2024-04-10 14:51:10 +01:00
|
|
|
'user_eqsl_qth_nickname' => "",
|
2011-08-18 01:31:15 +01:00
|
|
|
);
|
|
|
|
|
|
2011-08-19 17:13:26 +01:00
|
|
|
// Check the password is valid
|
|
|
|
|
if($data['user_password'] == EPASSWORDINVALID) {
|
|
|
|
|
return EPASSWORDINVALID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check the email address isn't in use
|
|
|
|
|
if($this->exists_by_email($email)) {
|
|
|
|
|
return EEMAILEXISTS;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 14:22:02 +00:00
|
|
|
// Check the callsign isn't in use
|
|
|
|
|
if($this->exists_by_callsign($callsign)) {
|
|
|
|
|
return ECALLSIGNEXISTS;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-06 12:32:54 +02:00
|
|
|
// Add user and insert bandsettings for user
|
2011-08-18 02:27:53 +01:00
|
|
|
$this->db->insert($this->config->item('auth_table'), $data);
|
2022-09-06 12:32:54 +02:00
|
|
|
$insert_id = $this->db->insert_id();
|
2022-10-05 22:13:12 +02:00
|
|
|
$this->db->query("insert into bandxuser (bandid, userid, active, cq, dok, dxcc, iota, pota, sig, sota, uscounties, was, wwff, vucc) select bands.id, " . $insert_id . ", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 from bands;");
|
2025-12-02 13:32:11 +00:00
|
|
|
$this->db->query("insert into awardxuser (userid, cq, dok, dxcc, ffma, iota, gridmaster_dl, gridmaster_lx, gridmaster_ja, gridmaster_us, gridmaster_uk, gmdxsummer, pota, sig, sota, uscounties, vucc, wab, waja, was, wwff) values (" . $insert_id . ", 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);");
|
2023-08-02 19:14:18 +02:00
|
|
|
$this->db->query("insert into paper_types (user_id,paper_name,metric,width,orientation,height) SELECT ".$insert_id.", paper_name, metric, width, orientation,height FROM paper_types where user_id = -1;");
|
2024-03-09 08:49:12 +01:00
|
|
|
$this->db->query("insert into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $insert_id . ", 'hamsat','hamsat_key','api','".xss_clean($user_hamsat_key)."');");
|
|
|
|
|
$this->db->query("insert into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $insert_id . ", 'hamsat','hamsat_key','workable','".xss_clean($user_hamsat_workable_only)."');");
|
2026-08-03 14:51:19 +01:00
|
|
|
$this->db->query("insert into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $insert_id . ", 'oscarwatch','api_token','value','');");
|
|
|
|
|
$this->db->query("insert into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $insert_id . ", 'oscarwatch','status_upload','enabled','0');");
|
2026-08-04 13:15:01 +01:00
|
|
|
$this->db->query("insert into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $insert_id . ", 'oscarwatch','force_amsat','enabled','0');");
|
2024-10-03 14:46:11 +01:00
|
|
|
|
|
|
|
|
$this->db->query("insert into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $insert_id . ", 'callbook','callbook_type','value','".xss_clean($callbook_type)."');");
|
|
|
|
|
$this->db->query("insert into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $insert_id . ", 'callbook','callbook_username','value','".xss_clean($callbook_username)."');");
|
|
|
|
|
|
|
|
|
|
// Load the encryption library
|
|
|
|
|
$this->load->library('encryption');
|
|
|
|
|
|
|
|
|
|
// Encrypt the password
|
|
|
|
|
$encrypted_password = $this->encryption->encrypt($callbook_password);
|
|
|
|
|
|
|
|
|
|
// Insert the encrypted password into the database
|
2024-10-03 14:48:44 +01:00
|
|
|
$this->db->query("INSERT INTO user_options (user_id, option_type, option_name, option_key, option_value) VALUES (" . $insert_id . ", 'callbook', 'callbook_password', 'value', '" . xss_clean($encrypted_password) . "');");
|
2024-10-03 14:46:11 +01:00
|
|
|
|
2011-08-19 17:13:26 +01:00
|
|
|
return OK;
|
2011-08-18 01:31:15 +01:00
|
|
|
} else {
|
2011-08-19 17:13:26 +01:00
|
|
|
return EUSERNAMEEXISTS;
|
2011-08-18 01:31:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-19 17:13:26 +01:00
|
|
|
// FUNCTION: bool edit()
|
2011-08-18 21:57:27 +02:00
|
|
|
// Edit a user
|
2011-08-19 20:33:37 +01:00
|
|
|
function edit($fields) {
|
|
|
|
|
|
|
|
|
|
// Check user privileges
|
|
|
|
|
if(($this->session->userdata('user_type') == 99) || ($this->session->userdata('user_id') == $fields['id'])) {
|
|
|
|
|
if($this->exists_by_id($fields['id'])) {
|
|
|
|
|
$data = array(
|
2025-11-24 14:22:34 +00:00
|
|
|
'user_name' => xss_clean($fields['user_name']),
|
|
|
|
|
'user_email' => xss_clean($fields['user_email']),
|
|
|
|
|
'user_callsign' => strtoupper(xss_clean($fields['user_callsign'])),
|
|
|
|
|
'user_locator' => xss_clean($fields['user_locator']),
|
|
|
|
|
'user_firstname' => xss_clean($fields['user_firstname']),
|
2019-10-05 21:57:44 +01:00
|
|
|
'user_lastname' => xss_clean($fields['user_lastname']),
|
|
|
|
|
'user_timezone' => xss_clean($fields['user_timezone']),
|
|
|
|
|
'user_lotw_name' => xss_clean($fields['user_lotw_name']),
|
|
|
|
|
'user_eqsl_name' => xss_clean($fields['user_eqsl_name']),
|
2025-10-13 13:40:56 +01:00
|
|
|
'user_clublog_name' => xss_clean($fields['user_clublog_name']), // Must be a valid email address - Clublog no longer accepts callsigns
|
2020-09-14 12:29:02 +02:00
|
|
|
'user_measurement_base' => xss_clean($fields['user_measurement_base']),
|
2020-09-15 22:04:47 +01:00
|
|
|
'user_date_format' => xss_clean($fields['user_date_format']),
|
2020-09-23 10:59:49 +02:00
|
|
|
'user_stylesheet' => xss_clean($fields['user_stylesheet']),
|
2022-10-19 16:27:26 +02:00
|
|
|
'user_qth_lookup' => xss_clean($fields['user_qth_lookup']),
|
2021-02-26 10:37:43 +01:00
|
|
|
'user_sota_lookup' => xss_clean($fields['user_sota_lookup']),
|
2022-10-19 14:52:43 +02:00
|
|
|
'user_wwff_lookup' => xss_clean($fields['user_wwff_lookup']),
|
2023-05-01 21:14:30 +02:00
|
|
|
'user_pota_lookup' => xss_clean($fields['user_pota_lookup']),
|
2021-03-20 21:19:07 +01:00
|
|
|
'user_show_notes' => xss_clean($fields['user_show_notes']),
|
2021-05-05 17:52:42 +02:00
|
|
|
'user_column1' => xss_clean($fields['user_column1']),
|
|
|
|
|
'user_column2' => xss_clean($fields['user_column2']),
|
|
|
|
|
'user_column3' => xss_clean($fields['user_column3']),
|
|
|
|
|
'user_column4' => xss_clean($fields['user_column4']),
|
2021-05-07 08:03:25 +02:00
|
|
|
'user_column5' => xss_clean($fields['user_column5']),
|
2022-07-03 11:39:05 +02:00
|
|
|
'user_show_profile_image' => xss_clean($fields['user_show_profile_image']),
|
2025-12-02 18:10:37 +00:00
|
|
|
'user_previous_qsl_type' => (int)$fields['user_previous_qsl_type'],
|
|
|
|
|
'user_amsat_status_upload' => (int)$fields['user_amsat_status_upload'],
|
2023-07-06 08:17:20 +00:00
|
|
|
'user_mastodon_url' => xss_clean($fields['user_mastodon_url']),
|
2023-10-16 22:39:33 +02:00
|
|
|
'user_default_band' => xss_clean($fields['user_default_band']),
|
2023-12-08 07:17:01 +00:00
|
|
|
'user_default_confirmation' => (isset($fields['user_default_confirmation_qsl']) ? 'Q' : '').(isset($fields['user_default_confirmation_lotw']) ? 'L' : '').(isset($fields['user_default_confirmation_eqsl']) ? 'E' : '').(isset($fields['user_default_confirmation_qrz']) ? 'Z' : ''),
|
2023-11-01 14:24:13 +01:00
|
|
|
'user_qso_end_times' => xss_clean($fields['user_qso_end_times']),
|
2023-11-04 18:36:08 +01:00
|
|
|
'user_quicklog' => xss_clean($fields['user_quicklog']),
|
2023-11-05 12:29:59 +01:00
|
|
|
'user_quicklog_enter' => xss_clean($fields['user_quicklog_enter']),
|
2023-08-02 06:34:12 +00:00
|
|
|
'language' => xss_clean($fields['language']),
|
2025-07-15 14:31:53 +01:00
|
|
|
'winkey' => (isset($fields['user_winkey']) && is_numeric($clean = xss_clean($fields['user_winkey'])) && $clean !== '') ? intval($clean) : 0,
|
2025-07-15 14:23:53 +01:00
|
|
|
'winkey_websocket' => isset($fields['user_winkey_websocket']) ? xss_clean($fields['user_winkey_websocket']) : 0,
|
2026-05-16 13:44:09 +01:00
|
|
|
'remote_operation' => isset($fields['user_remote_operation']) ? xss_clean($fields['user_remote_operation']) : 0,
|
2011-08-19 20:33:37 +01:00
|
|
|
);
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2024-03-09 08:49:12 +01:00
|
|
|
$this->db->query("replace into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $fields['id'] . ", 'hamsat','hamsat_key','api','".xss_clean($fields['user_hamsat_key'])."');");
|
|
|
|
|
$this->db->query("replace into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $fields['id'] . ", 'hamsat','hamsat_key','workable','".xss_clean($fields['user_hamsat_workable_only'])."');");
|
2026-08-03 14:45:59 +01:00
|
|
|
$this->db->query("replace into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $fields['id'] . ", 'oscarwatch','api_token','value','".xss_clean($fields['user_oscarwatch_token'] ?? '')."');");
|
2026-08-03 14:51:19 +01:00
|
|
|
$this->db->query("replace into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $fields['id'] . ", 'oscarwatch','status_upload','enabled','".(int)($fields['user_oscarwatch_status_upload'] ?? 0)."');");
|
2026-08-04 13:15:01 +01:00
|
|
|
$this->db->query("replace into user_options (user_id, option_type, option_name, option_key, option_value) values (" . $fields['id'] . ", 'oscarwatch','force_amsat','enabled','".(int)($fields['user_force_amsat_status_upload'] ?? 0)."');");
|
2024-03-09 08:49:12 +01:00
|
|
|
|
2011-08-19 20:33:37 +01:00
|
|
|
// Check to see if the user is allowed to change user levels
|
|
|
|
|
if($this->session->userdata('user_type') == 99) {
|
2026-03-26 14:22:02 +00:00
|
|
|
if ($this->would_remove_last_admin($fields['id'], $fields['user_type'])) {
|
|
|
|
|
return ELASTADMIN;
|
|
|
|
|
}
|
2011-08-19 20:33:37 +01:00
|
|
|
$data['user_type'] = $fields['user_type'];
|
|
|
|
|
}
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2011-08-19 20:33:37 +01:00
|
|
|
// Check to see if username is used already
|
|
|
|
|
if($this->exists($fields['user_name']) && $this->get($fields['user_name'])->row()->user_id != $fields['id']) {
|
|
|
|
|
return EUSERNAMEEXISTS;
|
|
|
|
|
}
|
|
|
|
|
// Check to see if email address is used already
|
|
|
|
|
if($this->exists_by_email($fields['user_email']) && $this->get_by_email($fields['user_email'])->row()->user_id != $fields['id']) {
|
|
|
|
|
return EEMAILEXISTS;
|
|
|
|
|
}
|
2026-03-26 14:22:02 +00:00
|
|
|
// Check to see if callsign is used already
|
|
|
|
|
if($this->exists_by_callsign($fields['user_callsign'], $fields['id'])) {
|
|
|
|
|
return ECALLSIGNEXISTS;
|
|
|
|
|
}
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2011-08-19 20:33:37 +01:00
|
|
|
// Hash password
|
|
|
|
|
if($fields['user_password'] != NULL)
|
|
|
|
|
{
|
|
|
|
|
$data['user_password'] = $this->_hash($fields['user_password']);
|
|
|
|
|
if($data['user_password'] == EPASSWORDINVALID) {
|
|
|
|
|
return EPASSWORDINVALID;
|
|
|
|
|
}
|
2011-08-19 17:13:26 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-17 08:54:16 -05:00
|
|
|
if($fields['user_lotw_password'] != NULL)
|
|
|
|
|
{
|
|
|
|
|
$data['user_lotw_password'] = $fields['user_lotw_password'];
|
|
|
|
|
}
|
2019-06-19 15:24:07 +01:00
|
|
|
|
|
|
|
|
if($fields['user_clublog_password'] != NULL)
|
|
|
|
|
{
|
|
|
|
|
$data['user_clublog_password'] = $fields['user_clublog_password'];
|
|
|
|
|
}
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2013-08-17 09:08:26 -05:00
|
|
|
if($fields['user_eqsl_password'] != NULL)
|
|
|
|
|
{
|
2026-07-18 22:53:51 +01:00
|
|
|
$this->load->library('encryption');
|
|
|
|
|
$encrypted_password = $this->encryption->encrypt($fields['user_eqsl_password']);
|
|
|
|
|
if ($encrypted_password !== false && $encrypted_password !== null) {
|
|
|
|
|
$data['user_eqsl_password'] = 'enc:' . $encrypted_password;
|
|
|
|
|
}
|
2013-08-17 09:08:26 -05:00
|
|
|
}
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2011-08-19 20:33:37 +01:00
|
|
|
// Update the user
|
|
|
|
|
$this->db->where('user_id', $fields['id']);
|
|
|
|
|
$this->db->update($this->config->item('auth_table'), $data);
|
|
|
|
|
return OK;
|
|
|
|
|
} else {
|
|
|
|
|
return ENOSUCHUSER;
|
|
|
|
|
}
|
2011-08-19 17:13:26 +01:00
|
|
|
} else {
|
2011-08-19 20:33:37 +01:00
|
|
|
return EFORBIDDEN;
|
2021-02-26 10:37:43 +01:00
|
|
|
}
|
2011-08-19 17:13:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FUNCTION: bool delete()
|
|
|
|
|
// Deletes a user
|
|
|
|
|
function delete($user_id) {
|
2011-08-18 01:31:15 +01:00
|
|
|
|
2011-08-19 17:13:26 +01:00
|
|
|
if($this->exists_by_id($user_id)) {
|
|
|
|
|
$this->db->query("DELETE FROM ".$this->config->item('auth_table')." WHERE user_id = '".$user_id."'");
|
2024-03-09 08:49:12 +01:00
|
|
|
$this->db->query("delete from user_options where user_id=?",$user_id);
|
2011-08-18 01:31:15 +01:00
|
|
|
|
2011-08-19 17:13:26 +01:00
|
|
|
return 1;
|
|
|
|
|
} else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2011-08-18 01:31:15 +01:00
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool login()
|
|
|
|
|
// Validates a username/password combination
|
|
|
|
|
// This is really just a wrapper around User_Model::authenticate
|
2011-08-18 01:31:15 +01:00
|
|
|
function login() {
|
2017-11-07 00:45:06 +00:00
|
|
|
|
2019-10-05 19:35:55 +01:00
|
|
|
$username = $this->input->post('user_name', true);
|
|
|
|
|
$password = $this->input->post('user_password', true);
|
2011-08-18 01:31:15 +01:00
|
|
|
|
|
|
|
|
return $this->authenticate($username, $password);
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: void clear_session()
|
|
|
|
|
// Clears a user's login session
|
|
|
|
|
// Nothing is returned - it can be assumed that if this is called, the user's
|
|
|
|
|
// login session *will* be cleared, no matter what state it is in
|
2011-08-18 01:31:15 +01:00
|
|
|
function clear_session() {
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2017-11-07 00:45:06 +00:00
|
|
|
$this->session->sess_destroy();
|
2011-08-18 01:31:15 +01:00
|
|
|
}
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: void update_session()
|
|
|
|
|
// Updates a user's login session after they've logged in
|
|
|
|
|
// TODO: This should return bool TRUE/FALSE or 0/1
|
2011-08-18 01:31:15 +01:00
|
|
|
function update_session($id) {
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2024-10-03 14:46:11 +01:00
|
|
|
$CI =& get_instance();
|
|
|
|
|
$CI->load->model('user_options_model');
|
|
|
|
|
$callbook_type_object = $CI->user_options_model->get_options('callbook')->result();
|
2026-05-16 13:44:09 +01:00
|
|
|
$remote_operation_option = $CI->user_options_model->get_options(
|
|
|
|
|
'remote_operation',
|
|
|
|
|
array('option_name' => 'enabled', 'option_key' => 'value'),
|
|
|
|
|
$id
|
|
|
|
|
)->row();
|
2026-04-08 22:26:05 +01:00
|
|
|
$show_qsl_cards_option = $CI->user_options_model->get_options(
|
|
|
|
|
'menu',
|
|
|
|
|
array('option_name' => 'show_qsl_cards', 'option_key' => 'enabled'),
|
|
|
|
|
$id
|
|
|
|
|
)->row();
|
2026-04-08 22:18:02 +01:00
|
|
|
$show_sstv_images_option = $CI->user_options_model->get_options(
|
|
|
|
|
'menu',
|
|
|
|
|
array('option_name' => 'show_sstv_images', 'option_key' => 'enabled'),
|
|
|
|
|
$id
|
|
|
|
|
)->row();
|
2026-08-03 14:51:19 +01:00
|
|
|
$oscarwatch_status_option = $CI->user_options_model->get_options(
|
|
|
|
|
'oscarwatch',
|
|
|
|
|
array('option_name' => 'status_upload', 'option_key' => 'enabled'),
|
|
|
|
|
$id
|
|
|
|
|
)->row();
|
2024-10-03 14:46:11 +01:00
|
|
|
|
|
|
|
|
// Get the callbook type
|
|
|
|
|
if (isset($callbook_type_object[1]->option_value)) {
|
|
|
|
|
$callbook_type = $callbook_type_object[1]->option_value;
|
|
|
|
|
} else {
|
|
|
|
|
$callbook_type = "None";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the callbook type
|
|
|
|
|
if (isset($callbook_type_object[2]->option_value)) {
|
|
|
|
|
$callbook_username = $callbook_type_object[2]->option_value;
|
|
|
|
|
} else {
|
|
|
|
|
$callbook_username = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the callbook type
|
|
|
|
|
if (isset($callbook_type_object[0]->option_value)) {
|
|
|
|
|
$callbook_password = $callbook_type_object[0]->option_value;
|
|
|
|
|
} else {
|
|
|
|
|
$callbook_password = "";
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 01:31:15 +01:00
|
|
|
$u = $this->get_by_id($id);
|
2026-04-08 22:18:02 +01:00
|
|
|
$has_eqsl_credentials = ($u->row()->user_eqsl_name != '' && $u->row()->user_eqsl_password != '');
|
2026-07-18 22:01:33 +01:00
|
|
|
if (!$has_eqsl_credentials) {
|
|
|
|
|
$this->load->model('eqsl_mappings_model');
|
|
|
|
|
$has_eqsl_credentials = $this->eqsl_mappings_model->has_mappings_for_user($id);
|
|
|
|
|
}
|
2026-04-08 22:26:05 +01:00
|
|
|
$show_qsl_cards = true;
|
|
|
|
|
if (isset($show_qsl_cards_option->option_value)) {
|
|
|
|
|
$show_qsl_cards = ($show_qsl_cards_option->option_value == 'true');
|
|
|
|
|
}
|
2026-04-08 22:18:02 +01:00
|
|
|
$show_sstv_images = false;
|
|
|
|
|
if (isset($show_sstv_images_option->option_value)) {
|
|
|
|
|
$show_sstv_images = ($show_sstv_images_option->option_value == 'true');
|
|
|
|
|
}
|
2026-08-03 14:51:19 +01:00
|
|
|
$oscarwatch_status_upload = 0;
|
|
|
|
|
if (isset($oscarwatch_status_option->option_value)) {
|
|
|
|
|
$oscarwatch_status_upload = (int) $oscarwatch_status_option->option_value;
|
|
|
|
|
}
|
2011-08-18 01:31:15 +01:00
|
|
|
|
|
|
|
|
$userdata = array(
|
2018-11-30 19:00:09 +00:00
|
|
|
'user_id' => $u->row()->user_id,
|
|
|
|
|
'user_name' => $u->row()->user_name,
|
|
|
|
|
'user_type' => $u->row()->user_type,
|
|
|
|
|
'user_callsign' => $u->row()->user_callsign,
|
2023-08-21 08:06:07 +00:00
|
|
|
'operator_callsign' => ((($this->session->userdata('operator_callsign') ?? '') == '') ? $u->row()->user_callsign : $this->session->userdata('operator_callsign')),
|
2018-11-30 19:00:09 +00:00
|
|
|
'user_locator' => $u->row()->user_locator,
|
|
|
|
|
'user_lotw_name' => $u->row()->user_lotw_name,
|
|
|
|
|
'user_eqsl_name' => $u->row()->user_eqsl_name,
|
|
|
|
|
'user_eqsl_qth_nickname' => $u->row()->user_eqsl_qth_nickname,
|
2026-04-08 22:18:02 +01:00
|
|
|
'has_eqsl_credentials' => $has_eqsl_credentials,
|
2026-04-08 22:26:05 +01:00
|
|
|
'user_show_qsl_cards' => $show_qsl_cards,
|
2026-04-08 22:18:02 +01:00
|
|
|
'user_show_sstv_images' => $show_sstv_images,
|
2019-06-25 13:46:13 +02:00
|
|
|
'user_hash' => $this->_hash($u->row()->user_id."-".$u->row()->user_type),
|
|
|
|
|
'radio' => isset($_COOKIE["radio"])?$_COOKIE["radio"]:"",
|
2020-09-14 12:29:02 +02:00
|
|
|
'station_profile_id' => isset($_COOKIE["station_profile_id"])?$_COOKIE["station_profile_id"]:"",
|
|
|
|
|
'user_measurement_base' => $u->row()->user_measurement_base,
|
2020-09-15 22:04:47 +01:00
|
|
|
'user_date_format' => $u->row()->user_date_format,
|
2020-09-23 10:59:49 +02:00
|
|
|
'user_stylesheet' => $u->row()->user_stylesheet,
|
2022-10-19 16:27:26 +02:00
|
|
|
'user_qth_lookup' => isset($u->row()->user_qth_lookup) ? $u->row()->user_qth_lookup : 0,
|
2021-07-20 15:07:55 +02:00
|
|
|
'user_sota_lookup' => isset($u->row()->user_sota_lookup) ? $u->row()->user_sota_lookup : 0,
|
2022-10-19 14:52:43 +02:00
|
|
|
'user_wwff_lookup' => isset($u->row()->user_wwff_lookup) ? $u->row()->user_wwff_lookup : 0,
|
2023-05-01 21:14:30 +02:00
|
|
|
'user_pota_lookup' => isset($u->row()->user_pota_lookup) ? $u->row()->user_pota_lookup : 0,
|
2021-07-20 15:07:55 +02:00
|
|
|
'user_show_notes' => isset($u->row()->user_show_notes) ? $u->row()->user_show_notes : 1,
|
2022-07-03 11:39:05 +02:00
|
|
|
'user_show_profile_image' => isset($u->row()->user_show_profile_image) ? $u->row()->user_show_profile_image : 0,
|
2021-07-20 15:07:55 +02:00
|
|
|
'user_column1' => isset($u->row()->user_column1) ? $u->row()->user_column1: 'Mode',
|
|
|
|
|
'user_column2' => isset($u->row()->user_column2) ? $u->row()->user_column2: 'RSTS',
|
|
|
|
|
'user_column3' => isset($u->row()->user_column3) ? $u->row()->user_column3: 'RSTR',
|
|
|
|
|
'user_column4' => isset($u->row()->user_column4) ? $u->row()->user_column4: 'Band',
|
|
|
|
|
'user_column5' => isset($u->row()->user_column5) ? $u->row()->user_column5: 'Country',
|
2022-11-25 00:22:31 +01:00
|
|
|
'user_previous_qsl_type' => isset($u->row()->user_previous_qsl_type) ? $u->row()->user_previous_qsl_type: 0,
|
2023-01-27 17:24:48 +01:00
|
|
|
'user_amsat_status_upload' => isset($u->row()->user_amsat_status_upload) ? $u->row()->user_amsat_status_upload: 0,
|
2026-08-03 14:51:19 +01:00
|
|
|
'user_oscarwatch_status_upload' => $oscarwatch_status_upload,
|
2023-07-06 08:17:20 +00:00
|
|
|
'user_mastodon_url' => $u->row()->user_mastodon_url,
|
2023-10-16 22:39:33 +02:00
|
|
|
'user_default_band' => $u->row()->user_default_band,
|
|
|
|
|
'user_default_confirmation' => $u->row()->user_default_confirmation,
|
2023-11-01 14:24:13 +01:00
|
|
|
'user_qso_end_times' => isset($u->row()->user_qso_end_times) ? $u->row()->user_qso_end_times : 1,
|
2023-11-04 18:31:59 +01:00
|
|
|
'user_quicklog' => isset($u->row()->user_quicklog) ? $u->row()->user_quicklog : 1,
|
2023-11-05 12:29:59 +01:00
|
|
|
'user_quicklog_enter' => isset($u->row()->user_quicklog_enter) ? $u->row()->user_quicklog_enter : 1,
|
2021-09-07 18:07:48 +01:00
|
|
|
'active_station_logbook' => $u->row()->active_station_logbook,
|
2023-08-02 06:34:12 +00:00
|
|
|
'language' => isset($u->row()->language) ? $u->row()->language: 'english',
|
2023-08-03 13:59:02 +01:00
|
|
|
'isWinkeyEnabled' => $u->row()->winkey,
|
2026-05-21 22:35:46 +01:00
|
|
|
'isWinkeyWebsocketEnabled' => isset($u->row()->winkey_websocket) ? (bool)$u->row()->winkey_websocket : false,
|
2026-05-16 13:44:09 +01:00
|
|
|
'isRemoteOperationEnabled' => (isset($remote_operation_option->option_value) ? ((string)$remote_operation_option->option_value === 'true' || (string)$remote_operation_option->option_value === '1') : (isset($u->row()->remote_operation) ? (bool)$u->row()->remote_operation : false)),
|
2024-10-03 14:46:11 +01:00
|
|
|
'hasQrzKey' => $this->hasQrzKey($u->row()->user_id),
|
|
|
|
|
'callbook_type' => $callbook_type,
|
|
|
|
|
'callbook_username' => $callbook_username,
|
|
|
|
|
'callbook_password' => $callbook_password,
|
2011-08-18 01:31:15 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->session->set_userdata($userdata);
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool validate_session()
|
|
|
|
|
// Validate a user's login session
|
|
|
|
|
// If the user's session is corrupted in any way, it will clear the session
|
2011-08-18 01:31:15 +01:00
|
|
|
function validate_session() {
|
|
|
|
|
|
2026-06-06 10:25:45 +01:00
|
|
|
if (!$this->session->userdata('user_id')) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2011-08-18 01:31:15 +01:00
|
|
|
|
2026-06-06 10:25:45 +01:00
|
|
|
$user_id = $this->session->userdata('user_id');
|
|
|
|
|
$user_hash = $this->session->userdata('user_hash');
|
|
|
|
|
|
|
|
|
|
if (empty($user_hash)) {
|
|
|
|
|
$this->clear_session();
|
2011-08-18 01:31:15 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
2026-06-06 10:25:45 +01:00
|
|
|
|
|
|
|
|
// Re-read the user from the database and validate against persisted state.
|
|
|
|
|
$u = $this->get_by_id($user_id);
|
|
|
|
|
if ($u->num_rows() !== 1) {
|
|
|
|
|
$this->clear_session();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$db_user_type = $u->row()->user_type;
|
|
|
|
|
|
|
|
|
|
if ($this->_auth($user_id."-".$db_user_type, $user_hash)) {
|
|
|
|
|
// Freshen the session
|
|
|
|
|
$this->update_session($user_id);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->clear_session();
|
|
|
|
|
return 0;
|
2011-08-18 01:31:15 +01:00
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool authenticate($username, $password)
|
|
|
|
|
// Authenticate a user against the users table
|
2011-08-18 01:31:15 +01:00
|
|
|
function authenticate($username, $password) {
|
|
|
|
|
$u = $this->get($username);
|
2017-11-07 00:45:06 +00:00
|
|
|
if($u->num_rows() != 0)
|
2011-08-18 01:31:15 +01:00
|
|
|
{
|
|
|
|
|
if($this->_auth($password, $u->row()->user_password)) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-01 02:08:12 +01:00
|
|
|
// FUNCTION: set's the last-login timestamp in user table
|
|
|
|
|
function set_last_login($user_id) {
|
|
|
|
|
$data = array(
|
|
|
|
|
'last_login_date' => date('Y-m-d H:i:s')
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->db->where('user_id', $user_id);
|
|
|
|
|
$this->db->update('users', $data);
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool authorize($level)
|
|
|
|
|
// Checks a user's level of access against the given $level
|
2011-08-18 01:31:15 +01:00
|
|
|
function authorize($level) {
|
|
|
|
|
$u = $this->get_by_id($this->session->userdata('user_id'));
|
2011-08-19 18:24:56 +01:00
|
|
|
$l = $this->config->item('auth_mode');
|
|
|
|
|
// Check to see if the minimum level of access is higher than
|
|
|
|
|
// the user's own level. If it is, use that.
|
|
|
|
|
if($this->config->item('auth_mode') > $level) {
|
|
|
|
|
$level = $this->config->item('auth_mode');
|
|
|
|
|
}
|
|
|
|
|
if(($this->validate_session()) && ($u->row()->user_type >= $level) || $this->config->item('use_auth') == FALSE || $level == 0) {
|
2011-08-18 01:31:15 +01:00
|
|
|
return 1;
|
|
|
|
|
} else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool set($username, $data)
|
|
|
|
|
// Updates a user's record in the database
|
|
|
|
|
// TODO: This returns TRUE/1 no matter what at the moment - should
|
|
|
|
|
// TODO: return TRUE/FALSE or 0/1 depending on success/failure
|
2011-08-18 01:31:15 +01:00
|
|
|
function set($username, $data) {
|
|
|
|
|
$this->db->where('user_name', $username);
|
|
|
|
|
$this->db->update($this->config->item('auth_table', $data));
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: object users()
|
|
|
|
|
// Returns a list of users
|
2011-08-18 01:31:15 +01:00
|
|
|
function users() {
|
|
|
|
|
$r = $this->db->get($this->config->item('auth_table'));
|
|
|
|
|
return $r;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-27 23:47:25 +01:00
|
|
|
// FUNCTION: array timezones()
|
|
|
|
|
// Returns a list of timezones
|
|
|
|
|
function timezones() {
|
2021-09-28 21:34:32 +02:00
|
|
|
$r = $this->db->query('SELECT id, name FROM timezones ORDER BY `offset`');
|
2011-09-27 23:47:25 +01:00
|
|
|
$ts = array();
|
|
|
|
|
foreach ($r->result_array() as $t) {
|
|
|
|
|
$ts[$t['id']] = $t['name'];
|
|
|
|
|
}
|
|
|
|
|
return $ts;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-09 13:13:41 +02:00
|
|
|
// FUNCTION: array getThemes()
|
|
|
|
|
// Returns a list of themes
|
|
|
|
|
function getThemes() {
|
|
|
|
|
$result = $this->db->query('SELECT * FROM themes order by name');
|
|
|
|
|
|
|
|
|
|
return $result->result();
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-18 15:29:22 +00:00
|
|
|
/*
|
|
|
|
|
* FUNCTION: set_password_reset_code
|
|
|
|
|
*
|
|
|
|
|
* Stores generated password reset code in the database and sets the date to exactly
|
|
|
|
|
* when the sql query runs.
|
2023-08-02 06:34:12 +00:00
|
|
|
*
|
2022-01-18 15:29:22 +00:00
|
|
|
* @param string $user_email
|
|
|
|
|
* @return string $reset_code
|
|
|
|
|
*/
|
|
|
|
|
function set_password_reset_code($user_email, $reset_code) {
|
|
|
|
|
$data = array(
|
|
|
|
|
'reset_password_code' => $reset_code,
|
|
|
|
|
'reset_password_date' => date('Y-m-d H:i:s')
|
|
|
|
|
);
|
2023-08-02 06:34:12 +00:00
|
|
|
|
2022-01-18 15:29:22 +00:00
|
|
|
$this->db->where('user_email', $user_email);
|
|
|
|
|
$this->db->update('users', $data);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-18 16:14:22 +00:00
|
|
|
/*
|
|
|
|
|
* FUNCTION: reset_password
|
|
|
|
|
*
|
|
|
|
|
* Sets new password for users account where the reset code matches then clears the password reset code and password reset date.
|
2023-08-02 06:34:12 +00:00
|
|
|
*
|
2022-01-18 16:14:22 +00:00
|
|
|
* @param string $password
|
|
|
|
|
* @return string $reset_code
|
|
|
|
|
*/
|
|
|
|
|
function reset_password($password, $reset_code) {
|
|
|
|
|
$data = array(
|
|
|
|
|
'user_password' => $this->_hash($password),
|
|
|
|
|
'reset_password_code' => NULL,
|
|
|
|
|
'reset_password_date' => NULL
|
|
|
|
|
);
|
2023-08-02 06:34:12 +00:00
|
|
|
|
2022-01-18 16:14:22 +00:00
|
|
|
$this->db->where('reset_password_code', $reset_code);
|
|
|
|
|
$this->db->update('users', $data);
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: bool _auth($password, $hash)
|
|
|
|
|
// Checks a password against the stored hash
|
2011-08-18 01:31:15 +01:00
|
|
|
private function _auth($password, $hash) {
|
2017-11-07 00:45:06 +00:00
|
|
|
if(password_verify($password, $hash)) {
|
2011-08-18 01:31:15 +01:00
|
|
|
return 1;
|
|
|
|
|
} else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-18 21:57:27 +02:00
|
|
|
// FUNCTION: string _hash($password)
|
|
|
|
|
// Returns a hashed version of the supplied $password
|
|
|
|
|
// Will return '0' in the event of problems with the
|
|
|
|
|
// hashing function
|
2011-08-18 01:31:15 +01:00
|
|
|
private function _hash($password) {
|
2021-02-26 10:37:43 +01:00
|
|
|
$hash = password_hash($password, PASSWORD_DEFAULT);
|
2011-08-18 01:31:15 +01:00
|
|
|
|
|
|
|
|
if(strlen($hash) < 20) {
|
2011-08-19 17:13:26 +01:00
|
|
|
return EPASSWORDINVALID;
|
2011-08-18 01:31:15 +01:00
|
|
|
} else {
|
|
|
|
|
return $hash;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-02-26 10:37:43 +01:00
|
|
|
|
2011-08-18 01:31:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
?>
|