-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ feat(big-bear-casaos-user-management): Add user management system (#27
) * ✨ feat(big-bear-casaos-user-management): Add user management system This commit introduces a new user management system for the BigBearCasaOS project. The key changes include: - Added a Dockerfile to build a Docker image for the user management system - Created a Docker Compose file to easily deploy the user management service - Implemented a Flask-based web application to manage user accounts - Added an HTML template for the user management interface - Configured environment variables for the admin username and password - Granted the container extended privileges and capabilities for system integration These changes enable the CasaOS platform to manage user accounts and roles, improving the overall security and usability of the system. * 🔧 feat(user-management): Enhance user management service configuration Modify the Docker Compose configuration for the CasaOS user management service: - Expose port 5000 on the host and map it to the container - Mount the cgroup filesystem in read-only mode for system resource monitoring - Persist the CasaOS database files to retain data across container restarts - Mount systemd's runtime directory for integration with the host system - Provide access to the D-Bus system bus for communication with host services - Set the Flask application entry point and production environment - Specify the admin username and password for the service - Grant the container extended privileges and the SYS_ADMIN capability - Disable the default seccomp security profile to allow unrestricted system calls - Rename the service from "big-bear-casaos-user-manager" to "big-bear-casaos-user-management" for consistency
- Loading branch information
1 parent
4d04b80
commit c4d10f0
Showing
9 changed files
with
508 additions
and
0 deletions.
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
.github/workflows/build_and_release_for_big_bear_casaos_user_management.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: "Build and release for big-bear-casaos-user-management" | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
paths: | ||
- "big-bear-casaos-user-management/**" | ||
|
||
jobs: | ||
create: | ||
name: "Creates the newest release by version" | ||
runs-on: "ubuntu-latest" | ||
|
||
steps: | ||
- name: Checkout project | ||
uses: actions/[email protected] | ||
|
||
# New step to read the VERSION file and set the version as an output | ||
- name: Get the version | ||
id: get_version | ||
run: echo "big_bear_casaos_user_management_version=$(cat big-bear-casaos-user-management/VERSION)" >> $GITHUB_ENV | ||
|
||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@master | ||
with: | ||
platforms: all | ||
|
||
- name: Set up Docker Build | ||
uses: docker/setup-buildx-action@v3 | ||
|
||
- name: Login to DockerHub | ||
uses: docker/login-action@v3 | ||
with: | ||
username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
||
- name: Build and push | ||
uses: docker/build-push-action@v3 | ||
with: | ||
push: true | ||
platforms: linux/amd64,linux/arm64 | ||
context: ./big-bear-casaos-user-management | ||
file: ./big-bear-casaos-user-management/Dockerfile | ||
tags: | | ||
bigbeartechworld/big-bear-casaos-user-management:latest | ||
bigbeartechworld/big-bear-casaos-user-management:${{ env.big_bear_casaos_user_management_version }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
FROM python:3.9-slim | ||
|
||
# Install system dependencies (systemd includes systemctl) | ||
RUN apt-get update && \ | ||
apt-get install -y systemd sudo && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# Create necessary directories | ||
RUN mkdir -p /var/lib/casaos/db | ||
|
||
# Set working directory | ||
WORKDIR /app | ||
|
||
# Copy all application files | ||
COPY app/ . | ||
|
||
# Install Python dependencies | ||
RUN pip install flask flask-wtf | ||
|
||
# Create a volume for persistent storage | ||
VOLUME /var/lib/casaos/db | ||
|
||
# Expose port for Flask | ||
EXPOSE 5000 | ||
|
||
# Run Flask app | ||
CMD ["python", "app.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
0.0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
from flask import Flask, render_template, redirect, url_for, flash, request | ||
from user_management import (list_users, add_user, edit_password, | ||
remove_user, reset_database, hash_password) | ||
from functools import wraps | ||
from flask import request, Response | ||
import os | ||
|
||
app = Flask(__name__) | ||
app.config['SECRET_KEY'] = 'your-secret-key' | ||
|
||
ADMIN_USERNAME = os.environ.get('ADMIN_USERNAME', 'admin') | ||
ADMIN_PASSWORD = os.environ.get('ADMIN_PASSWORD', 'YOUR_SECURE_PASSWORD') | ||
|
||
def check_auth(username, password): | ||
"""Verify admin credentials""" | ||
return username == ADMIN_USERNAME and password == ADMIN_PASSWORD | ||
|
||
def authenticate(): | ||
return Response( | ||
'Could not verify your access level for that URL.\n' | ||
'You have to login with proper credentials', 401, | ||
{'WWW-Authenticate': 'Basic realm="Login Required"'} | ||
) | ||
|
||
def requires_auth(f): | ||
@wraps(f) | ||
def decorated(*args, **kwargs): | ||
auth = request.authorization | ||
if not auth or not check_auth(auth.username, auth.password): | ||
return authenticate() | ||
return f(*args, **kwargs) | ||
return decorated | ||
|
||
@app.route('/') | ||
@requires_auth | ||
def index(): | ||
users = list_users(return_data=True) | ||
return render_template('index.html', users=users) | ||
|
||
@app.route('/add_user', methods=['POST']) | ||
def add_user_route(): | ||
username = request.form.get('username') | ||
password = request.form.get('password') | ||
if add_user(username, password): | ||
flash('User added successfully', 'success') | ||
return redirect(url_for('index')) | ||
|
||
@app.route('/edit_password', methods=['POST']) | ||
def edit_password_route(): | ||
user_id = request.form.get('user_id') | ||
new_password = request.form.get('new_password') | ||
if edit_password(user_id, new_password): | ||
flash('Password updated successfully', 'success') | ||
return redirect(url_for('index')) | ||
|
||
@app.route('/remove_user', methods=['POST']) | ||
def remove_user_route(): | ||
user_id = request.form.get('user_id') | ||
if remove_user(user_id): | ||
flash('User removed successfully', 'success') | ||
return redirect(url_for('index')) | ||
|
||
@app.route('/reset_database', methods=['POST']) | ||
@requires_auth | ||
def reset_database_route(): | ||
if reset_database(): | ||
flash('Database reset successfully', 'success') | ||
return redirect(url_for('index')) | ||
|
||
if __name__ == '__main__': | ||
app.run(host='0.0.0.0', port=5000, debug=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>BigBearCasaOS User Management</title> | ||
<link | ||
rel="stylesheet" | ||
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" | ||
/> | ||
<!-- Add before closing body tag --> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> | ||
</head> | ||
<body> | ||
<div class="container mt-4">{% block content %}{% endblock %}</div> | ||
</body> | ||
</html> |
128 changes: 128 additions & 0 deletions
128
big-bear-casaos-user-management/app/templates/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
{% extends "base.html" %} {% block content %} | ||
<h2>BigBearCasaOS User Management</h2> | ||
|
||
<!-- User List --> | ||
<div class="card mb-4"> | ||
<div class="card-header">Users</div> | ||
<div class="card-body"> | ||
<table class="table"> | ||
<thead> | ||
<tr> | ||
<th>ID</th> | ||
<th>Username</th> | ||
<th>Role</th> | ||
<th>Actions</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{% for user in users %} | ||
<tr> | ||
<td>{{ user[0] }}</td> | ||
<td>{{ user[1] }}</td> | ||
<td>{{ user[2] }}</td> | ||
<td> | ||
<button | ||
type="button" | ||
class="btn btn-sm btn-warning" | ||
data-bs-toggle="modal" | ||
data-bs-target="#editModal{{user[0]}}" | ||
> | ||
Edit | ||
</button> | ||
<form | ||
action="{{ url_for('remove_user_route') }}" | ||
method="POST" | ||
style="display: inline" | ||
> | ||
<input type="hidden" name="user_id" value="{{ user[0] }}" /> | ||
<button | ||
type="submit" | ||
class="btn btn-sm btn-danger" | ||
onclick="return confirm('Are you sure?')" | ||
> | ||
Remove | ||
</button> | ||
</form> | ||
</td> | ||
</tr> | ||
{% endfor %} | ||
</tbody> | ||
</table> | ||
|
||
<!-- Add this after the table --> | ||
{% for user in users %} | ||
<div class="modal fade" id="editModal{{user[0]}}" tabindex="-1"> | ||
<div class="modal-dialog"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<h5 class="modal-title">Edit User: {{user[1]}}</h5> | ||
<button | ||
type="button" | ||
class="btn-close" | ||
data-bs-dismiss="modal" | ||
></button> | ||
</div> | ||
<form action="{{ url_for('edit_password_route') }}" method="POST"> | ||
<div class="modal-body"> | ||
<input type="hidden" name="user_id" value="{{user[0]}}" /> | ||
<div class="mb-3"> | ||
<label>New Password</label> | ||
<input | ||
type="password" | ||
name="new_password" | ||
class="form-control" | ||
required | ||
/> | ||
</div> | ||
</div> | ||
<div class="modal-footer"> | ||
<button | ||
type="button" | ||
class="btn btn-secondary" | ||
data-bs-dismiss="modal" | ||
> | ||
Close | ||
</button> | ||
<button type="submit" class="btn btn-primary"> | ||
Save changes | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
{% endfor %} | ||
</div> | ||
</div> | ||
|
||
<!-- Add User Form --> | ||
<div class="card"> | ||
<div class="card-header">Add New User</div> | ||
<div class="card-body"> | ||
<form method="POST" action="{{ url_for('add_user_route') }}"> | ||
<div class="mb-3"> | ||
<label>Username</label> | ||
<input type="text" name="username" class="form-control" required /> | ||
</div> | ||
<div class="mb-3"> | ||
<label>Password</label> | ||
<input type="password" name="password" class="form-control" required /> | ||
</div> | ||
<button type="submit" class="btn btn-primary">Add User</button> | ||
</form> | ||
</div> | ||
</div> | ||
|
||
<div class="card mt-4"> | ||
<div class="card-header">Database Management</div> | ||
<div class="card-body"> | ||
<form | ||
action="{{ url_for('reset_database_route') }}" | ||
method="POST" | ||
onsubmit="return confirm('WARNING: This will delete all users! Are you sure?');" | ||
> | ||
<button type="submit" class="btn btn-danger">Reset Database</button> | ||
</form> | ||
</div> | ||
</div> | ||
{% endblock %} |
Oops, something went wrong.