Skip to content

Commit cfbd67a

Browse files
authored
Merge pull request wavelog#2680 from int2001/api_fence
Check Club-Keys more carefully on API
2 parents fbe838a + 082671d commit cfbd67a

File tree

2 files changed

+54
-4
lines changed

2 files changed

+54
-4
lines changed

application/controllers/Api.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,23 @@ function auth($key = '') {
119119

120120
function create_station($key = '') {
121121
$this->load->model('api_model');
122+
122123
if ($this->api_model->access($key) == "No Key Found" || $this->api_model->access($key) == "Key Disabled") {
123124
$this->output->set_status_header(401)->set_content_type('application/json')->set_output(json_encode(['status' => 'error', 'message' => 'Auth Error, invalid key']));
124125
return;
125126
}
127+
128+
$this->load->model('club_model');
129+
$userid = $this->api_model->key_userid($key);
130+
$created_by = $this->api_model->key_created_by($key);
131+
$club_perm = $this->club_model->get_permission_noui($userid,$created_by);
132+
if ($userid != $created_by) { // We're dealing with a Club Member/Member ADIF or Clubofficer
133+
if ((($club_perm ?? 0) == 3) || (($club_perm ?? 0) == 6)) { // Member or ADIF-Member? DENY
134+
$this->output->set_status_header(401)->set_content_type('application/json')->set_output(json_encode(['status' => 'error', 'message' => 'Auth Error, not enough grants for this operation']));
135+
return;
136+
}
137+
}
138+
126139
try {
127140
$raw = file_get_contents("php://input");
128141
if ($raw === false) {
@@ -149,8 +162,7 @@ function create_station($key = '') {
149162
$this->output->set_status_header(500)->set_content_type('application/json')->set_output(json_encode(['status' => 'error', 'message' => 'Processing error: ' . $e->getMessage()]));
150163
}
151164
$this->load->model('stationsetup_model');
152-
$user_id = $this->api_model->key_userid($key);
153-
$imported = $this->stationsetup_model->import_locations_parse($locations,$user_id);
165+
$imported = $this->stationsetup_model->import_locations_parse($locations,$userid);
154166
if (($imported[0] ?? '0') == 'limit') {
155167
$this->output->set_status_header(201)->set_content_type('application/json')->set_output(json_encode(['status' => 'success', 'message' => ($imported[1] ?? '0')." locations imported. Maximum limit of 1000 locations reached."]));
156168
} else {
@@ -224,6 +236,7 @@ function qso($dryrun = false) {
224236
$this->load->model('api_model');
225237

226238
$this->load->model('stations');
239+
$this->load->model('club_model');
227240

228241
if (!$this->load->is_loaded('Qra')) {
229242
$this->load->library('Qra');
@@ -252,6 +265,7 @@ function qso($dryrun = false) {
252265

253266
$userid = $this->api_model->key_userid($obj['key']);
254267
$created_by = $this->api_model->key_created_by($obj['key']);
268+
$club_perm = $this->club_model->get_permission_noui($userid,$created_by);
255269

256270
/**
257271
* As the API key user could use it also for clubstations we need to do an additional check here. Only if clubstations are enabled
@@ -260,12 +274,11 @@ function qso($dryrun = false) {
260274
* If the user is not the creator of the API key, it's likely a clubstation. In this case the callsign of the clubstation
261275
* can not be the same as the callsign of the user (operator call provided by the user). If this is the case, we need to use the callsign of the creator of the API key
262276
*/
263-
$real_operator = null;
277+
$real_operator = null; // real_operator is only filled if its a clubstation and the used key is created by an OP. otherwise its null
264278
if ($this->config->item('special_callsign')) {
265279
if ($userid != $created_by) {
266280
$this->load->model('user_model');
267281
$real_operator = $this->user_model->get_by_id($created_by)->row()->user_callsign;
268-
// TODO: It would be possible to check here if operator is allowed to use the clubstation, but this can be added later if needed
269282
} else {
270283
$real_operator = null;
271284
}
@@ -327,6 +340,11 @@ function qso($dryrun = false) {
327340
$record['operator'] = $real_operator;
328341
}
329342

343+
// in case the caller is an OP for a clubstation (real_operator is filled - see above) and the OP only has level 3 or 6 - take the OP from real_operator!
344+
if ($real_operator != null && ((($club_perm ?? 0) == 3) || (($club_perm ?? 0) == 6))) {
345+
$record['operator'] = $real_operator;
346+
}
347+
330348
if ((key_exists('gridsquare',$record)) && (($mygrid ?? '') != '') && (($record['gridsquare'] ?? '') != '') && (!(key_exists('distance',$record)))) {
331349
$record['distance'] = $this->qra->distance($mygrid, $record['gridsquare'], 'K');
332350
}

application/models/Club_model.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,38 @@ function club_authorize($level, $club_id, $user_id = NULL) {
5656
return false;
5757
}
5858

59+
/**
60+
* Get Permissionlevel for User in Club in a real model-way without UI
61+
*
62+
* @param int $club_id
63+
* @param int $user_id
64+
*
65+
* @return int
66+
*/
67+
function get_permission_noui($club_id, $user_id) {
68+
69+
if ($club_id == 0 || !is_numeric($club_id)) {
70+
return 0;
71+
}
72+
73+
if ($user_id == 0 || !is_numeric($user_id)) {
74+
return 0;
75+
}
76+
77+
$binding = [];
78+
$sql = 'SELECT p_level FROM `club_permissions` WHERE user_id = ? AND club_id = ?';
79+
$binding[] = $user_id;
80+
$binding[] = $club_id;
81+
82+
$query = $this->db->query($sql, $binding);
83+
84+
if ($query->num_rows() > 0) {
85+
return $query->row()->p_level;
86+
} else {
87+
return 0;
88+
}
89+
}
90+
5991
/**
6092
* Get Permissionlevel for User in Club
6193
*

0 commit comments

Comments
 (0)