Modify Added

main
Bryan Cerrati 2025-03-21 11:46:03 -04:00
parent 366ff7c78a
commit fb32bb7113
4 changed files with 446 additions and 330 deletions

View File

@ -1,12 +1,12 @@
from flask import Blueprint, render_template, request, redirect, url_for, flash
from app.models import Client, ClientPassword, Domain, PasswordCategory, RemoteCategory
from app.models import Client, ClientPassword, Domain, PasswordCategory, RemoteCategory, ClientRemote
from app import db
clients_bp = Blueprint('clients', __name__)
@clients_bp.route('/clients')
def clients():
clients_list = Client.query.all()
clients_list = Client.query.order_by(Client.name.asc()).all()
return render_template('clients.html', clients=clients_list)
@clients_bp.route('/clients/add', methods=['GET', 'POST'])
@ -209,3 +209,38 @@ def print_client(client_id):
available_remote_categories=available_remote_categories,
passwords_by_category=passwords_by_category,
remotes_by_category=remotes_by_category)
@clients_bp.route('/clients/<int:client_id>/edit_password/<int:password_id>', methods=['GET', 'POST'])
def edit_password(client_id, password_id):
password_item = ClientPassword.query.get_or_404(password_id)
if request.method == 'POST':
password_item.item = request.form.get('item')
password_item.username = request.form.get('username')
password_item.password = request.form.get('password')
password_item.ip_address = request.form.get('ip_address')
category_id = request.form.get('category_id')
if category_id:
password_item.category_id = int(category_id)
else:
password_item.category_id = None
db.session.commit()
flash("Password updated successfully", "success")
return redirect(url_for('clients.client_detail', client_id=client_id))
available_categories = PasswordCategory.query.all()
return render_template('edit_password.html', client_id=client_id, password=password_item, available_categories=available_categories)
@clients_bp.route('/clients/<int:client_id>/edit_remote/<int:remote_id>', methods=['GET', 'POST'])
def edit_remote(client_id, remote_id):
remote = ClientRemote.query.get_or_404(remote_id)
if request.method == 'POST':
# For remote editing, update fields based on the remote category.
remote.name = request.form.get('remote_name')
remote.ip_address = request.form.get('ip_address')
remote.port = request.form.get('port')
remote.psk = request.form.get('psk')
remote.address = request.form.get('address')
remote.details = request.form.get('details')
db.session.commit()
flash("Remote updated successfully", "success")
return redirect(url_for('clients.client_detail', client_id=client_id))
return render_template('edit_remote.html', client_id=client_id, remote=remote)

View File

@ -1,31 +1,24 @@
{% extends "base.html" %}
{% block title %}{{ client.name }}{% endblock %}
{% block content %}
<div class="text-center">
<div class="container">
<!-- Client Header -->
<div class="text-center my-4">
<h1 class="display-4">{{ client.name }}</h1>
</div>
</div>
<!-- Section 1: Details -->
<div class="mt-4">
<div class="text-center">
<!-- Details Section -->
<div class="mt-4">
<h2 class="text-center">Details</h2>
<div id="detailsDisplay" class="text-center">
<ul class="list-unstyled">
{% if client.phone %}
<li><strong>Phone:</strong> {{ client.phone }}</li>
{% endif %}
{% if client.address %}
<li><strong>Address:</strong> {{ client.address }}</li>
{% endif %}
{% if client.ip_address %}
<li><strong>IP Address:</strong> {{ client.ip_address }}</li>
{% endif %}
{% if client.subnet_mask %}
<li><strong>Subnet Mask:</strong> {{ client.subnet_mask }}</li>
{% endif %}
{% if client.gateway %}
<li><strong>Gateway:</strong> {{ client.gateway }}</li>
{% endif %}
{% if client.phone %}<li><strong>Phone:</strong> {{ client.phone }}</li>{% endif %}
{% if client.address %}<li><strong>Address:</strong> {{ client.address }}</li>{% endif %}
{% if client.ip_address %}<li><strong>IP Address:</strong> {{ client.ip_address }}</li>{% endif %}
{% if client.subnet_mask %}<li><strong>Subnet Mask:</strong> {{ client.subnet_mask }}</li>{% endif %}
{% if client.gateway %}<li><strong>Gateway:</strong> {{ client.gateway }}</li>{% endif %}
</ul>
{% if client.phone is none and client.address is none and client.ip_address is none and client.subnet_mask is none and client.gateway is none %}
{% if not (client.phone or client.address or client.ip_address or client.subnet_mask or client.gateway) %}
<p>No details available.</p>
{% endif %}
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#detailsForm" aria-expanded="false" aria-controls="detailsForm">
@ -56,16 +49,16 @@
<input type="text" class="form-control" name="gateway" value="{{ client.gateway or '' }}">
</div>
<button type="submit" class="btn btn-success">Update Details</button>
<button type="button" class="btn btn-secondary" data-toggle="collapse" data-target="#detailsForm">Cancel</button>
</form>
</div>
</div>
</div>
</div>
<hr>
<hr>
<!-- Section: Remote -->
<div class="mt-4">
<!-- Remote Section -->
<div class="mt-4">
<h2 class="section-title">Remote</h2>
{% for category, remotes in remotes_by_category.items() %}
{% if remotes|length > 0 %}
@ -108,7 +101,13 @@
{% for remote in remotes %}
<tr>
{% if category == 'RDP' %}
<td>{{ remote.name }}</td>
<td>
{% if remote.name %}
<a href="{{ url_for('clients.edit_remote', client_id=client.id, remote_id=remote.id) }}">{{ remote.name }}</a>
{% else %}
<a href="{{ url_for('clients.edit_remote', client_id=client.id, remote_id=remote.id) }}">Edit</a>
{% endif %}
</td>
<td>{{ remote.ip_address }}</td>
<td>{{ remote.port }}</td>
{% elif category == 'SSL-VPN' %}
@ -118,7 +117,13 @@
<td>{{ remote.ip_address }}</td>
<td>{{ remote.psk }}</td>
{% elif category == 'MGMT' %}
<td>{{ remote.name }}</td>
<td>
{% if remote.name %}
<a href="{{ url_for('clients.edit_remote', client_id=client.id, remote_id=remote.id) }}">{{ remote.name }}</a>
{% else %}
<a href="{{ url_for('clients.edit_remote', client_id=client.id, remote_id=remote.id) }}">Edit</a>
{% endif %}
</td>
<td><a href="{{ remote.address }}" target="_blank">{{ remote.address }}</a></td>
{% else %}
<td>{{ remote.details }}</td>
@ -154,12 +159,196 @@
<!-- Fields will be dynamically inserted by JavaScript -->
</div>
<button type="submit" class="btn btn-success">Add Remote</button>
<button type="button" class="btn btn-secondary" onclick="document.getElementById('remoteForm').style.display='none';">Cancel</button>
</form>
</div>
</div>
<hr>
<!-- Passwords Section -->
<div class="mt-4">
<h2 class="section-title">Passwords</h2>
{% for category, passwords in passwords_by_category.items() %}
{% if passwords|length > 0 %}
<h3 class="mt-3">{{ category }}</h3>
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th>Item</th>
<th>Username</th>
<th>Password</th>
<th>IP Address</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for p in passwords %}
<tr>
<td>
<a href="{{ url_for('clients.edit_password', client_id=client.id, password_id=p.id) }}">{{ p.item }}</a>
</td>
<td>{{ p.username }}</td>
<td>{{ p.password }}</td>
<td>{{ p.ip_address }}</td>
<td>
<form action="{{ url_for('clients.remove_password', client_id=client.id, password_id=p.id) }}" method="post" class="d-inline">
<button type="submit" class="btn btn-danger btn-sm"
onclick="return confirm('WARNING: Deleting this password is irreversible. Are you sure you want to delete this password?');">
Delete
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endfor %}
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#passwordForm" aria-expanded="false" aria-controls="passwordForm">
Add Password
</button>
<div class="collapse mt-3" id="passwordForm">
<div class="card card-body">
<form action="{{ url_for('clients.add_client_password', client_id=client.id) }}" method="post">
<div class="form-group">
<label for="item">Item:</label>
<input type="text" class="form-control" name="item" placeholder="Item">
</div>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" name="username" placeholder="Username">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="text" class="form-control" name="password" placeholder="Password">
</div>
<div class="form-group">
<label for="ip_address">IP Address:</label>
<input type="text" class="form-control" name="ip_address" placeholder="IP Address">
</div>
<div class="form-group">
<label for="category">Category:</label>
<select name="category_id" class="form-control">
{% for cat in available_categories %}
{% if cat.name == "General" %}
<option value="{{ cat.id }}" selected>{{ cat.name }}</option>
{% else %}
<option value="{{ cat.id }}">{{ cat.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-success">Add Password</button>
<button type="button" class="btn btn-secondary" data-toggle="collapse" data-target="#passwordForm">Cancel</button>
</form>
</div>
</div>
</div>
<hr>
<!-- Domains Section -->
<div class="mt-4">
<h2>Domains</h2>
{% if client.domains|length > 0 %}
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th>Domain</th>
<th>WHOIS Expiration</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for d in client.domains %}
<tr>
<td>{{ d.domain }}</td>
<td>{{ d.expiration_date }}</td>
<td>
<form action="{{ url_for('clients.remove_domain', client_id=client.id, domain_id=d.id) }}" method="post" class="d-inline">
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this domain association?');">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No domain associations.</p>
{% endif %}
<form action="{{ url_for('clients.attach_domain', client_id=client.id) }}" method="post" class="form-inline">
<div class="form-group mb-2">
<label for="domain_id" class="sr-only">Select Domain</label>
<select name="domain_id" class="form-control">
<option value="">General</option>
{% for d in available_domains %}
<option value="{{ d.id }}">{{ d.domain }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary mb-2 ml-2">Attach Domain</button>
</form>
</div>
<hr>
<!-- SSL Section -->
<div class="mt-4">
<h2>SSL</h2>
{% if client.ssl_domains|length > 0 %}
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th>Domain</th>
<th>SSL Expiration</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for d in client.ssl_domains %}
<tr>
<td>{{ d.domain }}</td>
<td>{{ d.ssl_expiration_date }}</td>
<td>
<form action="{{ url_for('clients.remove_ssl', client_id=client.id, domain_id=d.id) }}" method="post" class="d-inline">
<button type="submit" class="btn btn-danger btn-sm" onclick="return confirm('Are you sure you want to delete this SSL domain association?');">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No SSL associations.</p>
{% endif %}
<form action="{{ url_for('clients.attach_ssl', client_id=client.id) }}" method="post" class="form-inline">
<div class="form-group mb-2">
<label for="ssl_domain_id" class="sr-only">Select SSL Domain</label>
<select name="ssl_domain_id" class="form-control">
<option value="">General</option>
{% for d in available_ssl %}
<option value="{{ d.id }}">{{ d.domain }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary mb-2 ml-2">Attach SSL Domain</button>
</form>
</div>
<hr>
<!-- Delete Client and Print Buttons -->
<div class="mt-4 d-flex justify-content-between">
<form action="{{ url_for('clients.delete_client', client_id=client.id) }}" method="post" onsubmit="return confirm('WARNING: Deleting this client will remove all associated data. Are you sure you want to proceed?');">
<button type="submit" class="btn btn-danger btn-block">Delete Client</button>
</form>
<a href="{{ url_for('clients.print_client', client_id=client.id) }}" class="btn btn-secondary btn-block ml-2" target="_blank">Print</a>
</div>
</div>
<script>
// Toggle the remote form display when the button is clicked
// Toggle the remote form display when the "Add Remote" button is clicked
document.getElementById("toggleRemoteFormBtn").addEventListener("click", function(){
var formDiv = document.getElementById("remoteForm");
if(formDiv.style.display === "none"){
@ -196,196 +385,4 @@
changeRemoteFormFields();
});
</script>
<hr>
<!-- Section 2: Passwords -->
<div class="mt-4">
<h2 class="section-title">Passwords</h2>
{% for category, passwords in passwords_by_category.items() %}
{% if passwords|length > 0 %}
<h3 class="mt-3">{{ category }}</h3>
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th>Item</th>
<th>Username</th>
<th>Password</th>
<th>IP Address</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for p in passwords %}
<tr>
<td>{{ p.item }}</td>
<td>{{ p.username }}</td>
<td>{{ p.password }}</td>
<td>{{ p.ip_address }}</td>
<td>
<form action="{{ url_for('clients.remove_password', client_id=client.id, password_id=p.id) }}" method="post" class="d-inline">
<button type="submit" class="btn btn-danger btn-sm"
onclick="return confirm('WARNING: Deleting this password is irreversible. Are you sure you want to delete this password?');">
Delete
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% endfor %}
<!-- Add Password Form (hidden by default) -->
<button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#passwordForm" aria-expanded="false" aria-controls="passwordForm">
Add Password
</button>
<div class="collapse mt-3" id="passwordForm">
<div class="card card-body">
<form action="{{ url_for('clients.add_client_password', client_id=client.id) }}" method="post">
<div class="form-group">
<label for="item">Item:</label>
<input type="text" class="form-control" name="item" placeholder="Item">
</div>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" name="username" placeholder="Username">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="text" class="form-control" name="password" placeholder="Password">
</div>
<div class="form-group">
<label for="ip_address">IP Address:</label>
<input type="text" class="form-control" name="ip_address" placeholder="IP Address">
</div>
<div class="form-group">
<label for="category">Category:</label>
<select name="category_id" class="form-control">
{% for cat in available_categories %}
{% if cat.name == "General" %}
<option value="{{ cat.id }}" selected>{{ cat.name }}</option>
{% else %}
<option value="{{ cat.id }}">{{ cat.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-success">Add Password</button>
</form>
</div>
</div>
</div>
<hr>
<!-- Section 3: Domains -->
<div class="mt-4">
<h2 class="section-title">Domains</h2>
{% if client.domains|length > 0 %}
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th>Domain</th>
<th>WHOIS Expiration</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for d in client.domains %}
<tr>
<td>{{ d.domain }}</td>
<td>{{ d.expiration_date }}</td>
<td>
<form action="{{ url_for('clients.remove_domain', client_id=client.id, domain_id=d.id) }}" method="post" class="d-inline">
<button type="submit" class="btn btn-danger btn-sm"
onclick="return confirm('Are you sure you want to delete this domain association?');">
Delete
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No domain associations.</p>
{% endif %}
<form action="{{ url_for('clients.attach_domain', client_id=client.id) }}" method="post" class="form-inline">
<div class="form-group mb-2">
<label for="domain_id" class="sr-only">Select Domain</label>
<select name="domain_id" class="form-control">
<option value="">General</option>
{% for d in available_domains %}
<option value="{{ d.id }}">{{ d.domain }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary mb-2 ml-2">Attach Domain</button>
</form>
</div>
<hr>
<!-- Section 4: SSL -->
<div class="mt-4">
<h2 class="section-title">SSL</h2>
{% if client.ssl_domains|length > 0 %}
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th>Domain</th>
<th>SSL Expiration</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for d in client.ssl_domains %}
<tr>
<td>{{ d.domain }}</td>
<td>{{ d.ssl_expiration_date }}</td>
<td>
<form action="{{ url_for('clients.remove_ssl', client_id=client.id, domain_id=d.id) }}" method="post" class="d-inline">
<button type="submit" class="btn btn-danger btn-sm"
onclick="return confirm('Are you sure you want to delete this SSL domain association?');">
Delete
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No SSL associations.</p>
{% endif %}
<form action="{{ url_for('clients.attach_ssl', client_id=client.id) }}" method="post" class="form-inline">
<div class="form-group mb-2">
<label for="ssl_domain_id" class="sr-only">Select SSL Domain</label>
<select name="ssl_domain_id" class="form-control">
<option value="">General</option>
{% for d in available_ssl %}
<option value="{{ d.id }}">{{ d.domain }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary mb-2 ml-2">Attach SSL Domain</button>
</form>
</div>
<hr>
<!-- Delete Client Section -->
<div class="mt-4 d-flex justify-content-between">
<form action="{{ url_for('clients.delete_client', client_id=client.id) }}" method="post" onsubmit="return confirm('WARNING: Deleting this client will remove all associated data. Are you sure you want to proceed?');">
<button type="submit" class="btn btn-danger btn-block">Delete Client</button>
</form>
<a href="{{ url_for('clients.print_client', client_id=client.id) }}" class="btn btn-secondary btn-block ml-2" target="_blank">Print</a>
</div>
{% endblock %}

View File

@ -0,0 +1,36 @@
{% extends "base.html" %}
{% block title %}Edit Password{% endblock %}
{% block content %}
<div class="container">
<h1>Edit Password</h1>
<form method="post">
<div class="form-group">
<label for="item">Item:</label>
<input type="text" name="item" class="form-control" value="{{ password.item }}">
</div>
<div class="form-group">
<label for="username">Username:</label>
<input type="text" name="username" class="form-control" value="{{ password.username }}">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="text" name="password" class="form-control" value="{{ password.password }}">
</div>
<div class="form-group">
<label for="ip_address">IP Address:</label>
<input type="text" name="ip_address" class="form-control" value="{{ password.ip_address }}">
</div>
<div class="form-group">
<label for="category_id">Category:</label>
<select name="category_id" class="form-control">
<option value="">Select Category</option>
{% for cat in available_categories %}
<option value="{{ cat.id }}" {% if password.category and password.category.id == cat.id %}selected{% endif %}>{{ cat.name }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-success">Save Changes</button>
<a href="{{ url_for('clients.client_detail', client_id=client_id) }}" class="btn btn-secondary">Cancel</a>
</form>
</div>
{% endblock %}

View File

@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block title %}Edit Remote{% endblock %}
{% block content %}
<div class="container">
<h1>Edit Remote</h1>
<form method="post">
{% set category = remote.remote_category.name %}
{% if category in ['RDP', 'MGMT'] %}
<div class="form-group">
<label for="remote_name">Name:</label>
<input type="text" name="remote_name" class="form-control" value="{{ remote.name }}">
</div>
{% endif %}
{% if category in ['RDP', 'SSL-VPN', 'VPN'] %}
<div class="form-group">
<label for="ip_address">IP Address:</label>
<input type="text" name="ip_address" class="form-control" value="{{ remote.ip_address }}">
</div>
{% endif %}
{% if category in ['RDP', 'SSL-VPN'] %}
<div class="form-group">
<label for="port">Port:</label>
<input type="text" name="port" class="form-control" value="{{ remote.port }}">
</div>
{% endif %}
{% if category == 'VPN' %}
<div class="form-group">
<label for="psk">PSK:</label>
<input type="text" name="psk" class="form-control" value="{{ remote.psk }}">
</div>
{% endif %}
{% if category == 'MGMT' %}
<div class="form-group">
<label for="address">Address (URL):</label>
<input type="text" name="address" class="form-control" value="{{ remote.address }}">
</div>
{% endif %}
{% if category not in ['RDP', 'SSL-VPN', 'VPN', 'MGMT'] %}
<div class="form-group">
<label for="details">Details:</label>
<input type="text" name="details" class="form-control" value="{{ remote.details }}">
</div>
{% endif %}
<button type="submit" class="btn btn-success">Save Changes</button>
<a href="{{ url_for('clients.client_detail', client_id=client_id) }}" class="btn btn-secondary">Cancel</a>
</form>
</div>
{% endblock %}