change to user_list to fetch from radusergroup / groupname

This commit is contained in:
2025-03-28 16:27:53 -04:00
parent 396fd2f3b4
commit 2d0247d0d9
2 changed files with 51 additions and 32 deletions

View File

@@ -96,12 +96,12 @@ def user_list():
cursor.execute(""" cursor.execute("""
SELECT SELECT
rc.username AS mac_address, rc.username AS mac_address,
IFNULL((SELECT value FROM radgroupreply rgr IFNULL(rug.groupname, 'N/A') AS vlan_id, -- Changed to get groupname from radusergroup
WHERE rgr.groupname = (SELECT groupname FROM radusergroup rug WHERE rug.username = rc.username LIMIT 1)
AND rgr.attribute = 'Tunnel-Private-Group-Id' LIMIT 1), 'N/A') AS vlan_id,
IFNULL((SELECT value FROM radcheck rch IFNULL((SELECT value FROM radcheck rch
WHERE rch.username = rc.username AND rch.attribute = 'User-Description' LIMIT 1), 'N/A') AS description WHERE rch.username = rc.username AND rch.attribute = 'User-Description' LIMIT 1), 'N/A') AS description
FROM radcheck rc FROM radcheck rc
LEFT JOIN radusergroup rug ON rc.username = rug.username -- Join radcheck and radusergroup
WHERE rc.attribute = 'Cleartext-Password'
GROUP BY rc.username; GROUP BY rc.username;
""") """)
results = cursor.fetchall() results = cursor.fetchall()

View File

@@ -19,7 +19,15 @@
<tr> <tr>
<td><input type="text" id="mac_address-{{ user.mac_address }}" value="{{ user.mac_address }}"></td> <td><input type="text" id="mac_address-{{ user.mac_address }}" value="{{ user.mac_address }}"></td>
<td><input type="text" id="description-{{ user.mac_address }}" value="{{ user.description }}"></td> <td><input type="text" id="description-{{ user.mac_address }}" value="{{ user.description }}"></td>
<td><input type="text" id="vlan_id-{{ user.mac_address }}" value="{{ user.vlan_id }}"></td> <td>
<select id="vlan_id-{{ user.mac_address }}">
{% for group in groups %}
<option value="{{ group.groupname }}" {% if user.groupname == group.groupname %} selected {% endif %}>
{{ group.groupname }}
</option>
{% endfor %}
</select>
</td>
<td> <td>
<button onclick="updateUser('{{ user.mac_address }}')"></button> <button onclick="updateUser('{{ user.mac_address }}')"></button>
<button onclick="location.reload()"></button> <button onclick="location.reload()"></button>
@@ -50,7 +58,15 @@
<tr> <tr>
<td><input type="text" id="new-mac"></td> <td><input type="text" id="new-mac"></td>
<td><input type="text" id="new-description"></td> <td><input type="text" id="new-description"></td>
<td><input type="text" id="new-vlan_id"></td> <td>
<select id="new-vlan_id">
{% for group in groups %}
<option value="{{ group.groupname }}">
{{ group.groupname }}
</option>
{% endfor %}
</select>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -110,14 +126,14 @@
function updateUser(mac_address) { function updateUser(mac_address) {
const description = document.getElementById('description-' + mac_address).value; const description = document.getElementById('description-' + mac_address).value;
const vlan_id = document.getElementById('vlan_id-' + mac_address).value; const vlan_id = document.getElementById('vlan_id-' + mac_address).value;
const mac_address_input = document.getElementById('mac_address-' + mac_address).value; //added const mac_address_input = document.getElementById('mac_address-' + mac_address).value;
fetch('/update_user', { fetch('/update_user', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/x-www-form-urlencoded', 'Content-Type': 'application/x-www-form-urlencoded',
}, },
body: `mac_address=${mac_address}&description=${description}&vlan_id=${vlan_id}&new_mac_address=${mac_address_input}` //added new param body: `mac_address=${mac_address}&description=${description}&vlan_id=${vlan_id}&new_mac_address=${mac_address_input}`
}) })
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
@@ -141,8 +157,6 @@
} }
} }
function duplicateUser(mac_address) { function duplicateUser(mac_address) {
fetch('/duplicate_user', { fetch('/duplicate_user', {
method: 'POST', method: 'POST',
@@ -166,11 +180,17 @@
<tr> <tr>
<td><input type="text" id="new-mac" value="${userData.mac_address}"></td> <td><input type="text" id="new-mac" value="${userData.mac_address}"></td>
<td><input type="text" class="new-description" value="${userData.description}"></td> <td><input type="text" class="new-description" value="${userData.description}"></td>
<td><input type="text" class="new-vlan_id" value="${userData.vlan_id}"></td> <td>
<select id="new-vlan_id">
{% for group in groups %}
<option value="{{ group.groupname }}" ${userData.vlan_id === group.groupname ? 'selected' : ''}>
{{ group.groupname }}
</option>
{% endfor %}
</select>
</td>
</tr>`; </tr>`;
newTable += `<tr> newTable += `<tr>
<td colspan="3" class="merged-cell"> <td colspan="3" class="merged-cell">
<button onclick="addDuplicatedUserRow(this)"></button> <button onclick="addDuplicatedUserRow(this)"></button>
@@ -192,20 +212,18 @@
function saveDuplicatedUser() { function saveDuplicatedUser() {
let rows = document.querySelectorAll('#duplicate-dialog-content table tbody tr'); let rows = document.querySelectorAll('#duplicate-dialog-content table tbody tr');
let new_mac_address = rows[0].querySelector('#new-mac').value; //changed let new_mac_address = rows[0].querySelector('#new-mac').value;
let attributes = []; let attributes = [];
for (let i = 1; i < rows.length - 1; i++) { for (let i = 1; i < rows.length - 1; i++) {
const descriptionInput = rows[i].querySelector(`.new-description`); const descriptionInput = rows[i].querySelector(`.new-description`);
const vlanIdInput = rows[i].querySelector(`.new-vlan_id`); const vlanIdInput = rows[i].querySelector(`.new-vlan_id`);
if (descriptionInput && vlanIdInput) { if (descriptionInput && vlanIdInput) {
attributes.push({ attributes.push({
description: descriptionInput.value, description: descriptionInput.value,
vlan_id: vlanIdInput.value, vlan_id: vlanIdInput.value,
}); });
} else { } else {
console.warn(`Input elements not found for row ${i}`); console.warn(`Input elements not found for row ${i}`);
return; return;
} }
@@ -216,7 +234,7 @@
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify({ mac_address: new_mac_address, attributes: attributes }) //changed body: JSON.stringify({ mac_address: new_mac_address, attributes: attributes })
}) })
.then(response => response.text()) .then(response => response.text())
.then(data => { .then(data => {
@@ -230,21 +248,23 @@
} }
function addDuplicatedUserRow(button) { function addDuplicatedUserRow(button) {
const table = button.parentNode.parentNode.parentNode; //get the table const table = button.parentNode.parentNode.parentNode;
const newRow = table.insertRow(table.rows.length - 1); const newRow = table.insertRow(table.rows.length - 1);
const cell1 = newRow.insertCell(0); const cell1 = newRow.insertCell(0);
const cell2 = newRow.insertCell(1); const cell2 = newRow.insertCell(1);
const cell3 = newRow.insertCell(2); const cell3 = newRow.insertCell(2);
const cell4 = newRow.insertCell(3); const cell4 = newRow.insertCell(3);
cell1.classList.add('merged-cell'); cell1.classList.add('merged-cell');
cell2.innerHTML = `<input type="text" class="new-description" value="">`; cell2.innerHTML = `<input type="text" class="new-description" value="">`;
cell3.innerHTML = `<input type="text" class="new-vlan_id" value="">`; cell3.innerHTML = `<select class="new-vlan_id">
{% for group in groups %}
<option value="{{ group.groupname }}">
{{ group.groupname }}
</option>
{% endfor %}
</select>`;
cell4.innerHTML = `<button onclick="removeDuplicatedUserRow(this)">🗑️</button>`; cell4.innerHTML = `<button onclick="removeDuplicatedUserRow(this)">🗑️</button>`;
} }
@@ -282,34 +302,33 @@
vlan_id: vlan_id vlan_id: vlan_id
}; };
fetch('/add_user', { // Make sure this URL is correct fetch('/add_user', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', // Set the content type to JSON 'Content-Type': 'application/json',
}, },
body: JSON.stringify(userData), // Send the data as a JSON string body: JSON.stringify(userData),
}) })
.then(response => { .then(response => {
if (!response.ok) { if (!response.ok) {
// Handle HTTP errors (e.g., 400, 500)
return response.text().then(text => { return response.text().then(text => {
throw new Error(`HTTP error! status: ${response.status}, body: ${text}`); throw new Error(`HTTP error! status: ${response.status}, body: ${text}`);
}); });
} }
return response.json(); // Expect JSON response from server return response.json();
}) })
.then(data => { .then(data => {
console.log("Server response:", data); console.log("Server response:", data);
if (data && data.success) { // Check for success property in JSON response if (data && data.success) {
document.getElementById('add-user-dialog').close(); document.getElementById('add-user-dialog').close();
location.reload(); location.reload();
} else { } else {
alert('Error adding user: ' + (data && data.message ? data.message : 'Unknown error')); // Show error from server or a generic message alert('Error adding user: ' + (data && data.message ? data.message : 'Unknown error'));
} }
}) })
.catch(error => { .catch(error => {
console.error('Fetch error:', error); // Log the error for debugging console.error('Fetch error:', error);
alert('Error adding user: ' + error.message); // Show a user-friendly error message alert('Error adding user: ' + error.message);
}); });
} }
</script> </script>