write query profile
This commit is contained in:
@ -33,3 +33,9 @@ class AddUserForm(FlaskForm):
|
|||||||
InputRequired(message='Privilege is required.'),
|
InputRequired(message='Privilege is required.'),
|
||||||
Regexp(r'^[0-9]$|^10$', message='Privilege must be an integer between 0 and 10.')
|
Regexp(r'^[0-9]$|^10$', message='Privilege must be an integer between 0 and 10.')
|
||||||
])
|
])
|
||||||
|
|
||||||
|
class QueryProfileForm(FlaskForm):
|
||||||
|
username = StringField('Username', validators=[
|
||||||
|
InputRequired(message='Username is required.'),
|
||||||
|
Regexp(r'^[a-zA-Z][a-zA-Z0-9_]{0,19}$', message='Username must start with a letter and can only contain letters, numbers, and underscores (max 20 characters).')
|
||||||
|
])
|
34
UI/main.py
34
UI/main.py
@ -156,3 +156,37 @@ def add_user():
|
|||||||
flash(error, 'danger')
|
flash(error, 'danger')
|
||||||
|
|
||||||
return render_template('adduser.html', form=form)
|
return render_template('adduser.html', form=form)
|
||||||
|
|
||||||
|
@app.route('/admin/queryprofile', methods=['GET', 'POST'])
|
||||||
|
def query_profile():
|
||||||
|
if 'username' not in session or utils.GetPrivilege(session['username'], ExecCommand) < 10:
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
form = QueryProfileForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
cur_username = session['username']
|
||||||
|
query_username = form.username.data
|
||||||
|
|
||||||
|
# 调用 ExecCommand 执行查询命令
|
||||||
|
query_response = ExecCommand(f'query_profile -c {cur_username} -u {query_username}')
|
||||||
|
|
||||||
|
if query_response.strip() == '-1':
|
||||||
|
error = 'Failed to retrieve profile.'
|
||||||
|
flash(error, 'danger')
|
||||||
|
return redirect(url_for('query_profile'))
|
||||||
|
else:
|
||||||
|
profile_data = query_response.split(' ')
|
||||||
|
if len(profile_data) >= 4:
|
||||||
|
user_info = {
|
||||||
|
'username': profile_data[0],
|
||||||
|
'name': profile_data[1],
|
||||||
|
'email': profile_data[2],
|
||||||
|
'privilege': profile_data[3]
|
||||||
|
}
|
||||||
|
return render_template('queryprofile.html', user_info=user_info, form=form)
|
||||||
|
else:
|
||||||
|
error = "Profile data is incomplete or incorrect."
|
||||||
|
flash(error, 'danger')
|
||||||
|
return redirect(url_for('query_profile'))
|
||||||
|
|
||||||
|
return render_template('queryprofile.html', form=form)
|
@ -25,7 +25,7 @@
|
|||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username">Username</label>
|
<label for="username">Username</label>
|
||||||
<input type="text" class="form-control" id="username" name="username" placeholder="Enter username" pattern="^[a-zA-Z][a-zA-Z0-9_]{0,19}$" required>
|
<input type="text" class="form-control" id="username" name="username" placeholder="Enter username" maxlength="20" pattern="^[a-zA-Z][a-zA-Z0-9_]{0,19}$" required>
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
Username must start with a letter and can only contain letters, numbers, and underscores (max 20 characters).
|
Username must start with a letter and can only contain letters, numbers, and underscores (max 20 characters).
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="adminDropdown">
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="adminDropdown">
|
||||||
<a class="dropdown-item" href="/admin/adduser">AddUser</a>
|
<a class="dropdown-item" href="/admin/adduser">AddUser</a>
|
||||||
|
<a class="dropdown-item" href="/admin/queryprofile">QueryProfile</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
|
86
UI/templates/queryprofile.html
Normal file
86
UI/templates/queryprofile.html
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Query Profile{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h2 class="text-center">Query User Profile</h2>
|
||||||
|
|
||||||
|
<!-- Flash messages -->
|
||||||
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
|
{% if messages %}
|
||||||
|
{% for category, message in messages %}
|
||||||
|
<div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
|
||||||
|
{{ message }}
|
||||||
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
|
||||||
|
<form id="queryForm" class="needs-validation" novalidate method="POST" action="/admin/queryprofile">
|
||||||
|
{{ form.hidden_tag() }}
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
{{ form.username(class="form-control", placeholder="Enter the username to query", id="username", maxlength="20", pattern="^[a-zA-Z][a-zA-Z0-9_]{0,19}$") }}
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
Username must start with a letter and can only contain letters, numbers, and underscores (max 20 characters).
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary btn-block">Query</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% if user_info %}
|
||||||
|
<div class="card mt-4 border-custom">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">{{ user_info.name }}</h4>
|
||||||
|
<p class="card-text"><strong>Username:</strong> {{ user_info.username }}</p>
|
||||||
|
<p class="card-text"><strong>Email:</strong> {{ user_info.email }}</p>
|
||||||
|
<p class="card-text"><strong>Privilege:</strong> {{ user_info.privilege }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// JavaScript for form validation
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const queryForm = document.getElementById('queryForm');
|
||||||
|
queryForm.addEventListener('submit', function(event) {
|
||||||
|
if (!queryForm.checkValidity()) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
queryForm.classList.add('was-validated');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Real-time validation for username
|
||||||
|
const usernameInput = document.getElementById('username');
|
||||||
|
usernameInput.addEventListener('input', function() {
|
||||||
|
if (usernameInput.checkValidity()) {
|
||||||
|
usernameInput.classList.remove('is-invalid');
|
||||||
|
usernameInput.classList.add('is-valid');
|
||||||
|
} else {
|
||||||
|
usernameInput.classList.remove('is-valid');
|
||||||
|
usernameInput.classList.add('is-invalid');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.border-custom {
|
||||||
|
border: 2px solid #007bff; /* 蓝色边框 */
|
||||||
|
border-radius: 15px; /* 圆角边框 */
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
|
||||||
|
}
|
||||||
|
.card-body {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{% endblock %}
|
Reference in New Issue
Block a user