29 Commits

Author SHA1 Message Date
Gitea Actions
fdc5b46ef3 Update manifest version to 7.1.7 [▶️] 2025-12-22 01:49:29 +00:00
7aa47b74b9 Merge branch 'main' of https://git.icc.gg/ivancarlos/bundledcmdb
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 23m1s
2025-12-21 22:49:10 -03:00
fa056218d8 fix readme updater not working 2025-12-21 22:49:03 -03:00
Gitea Actions
c4cb329139 Update manifest version to 7.1.6 [▶️] 2025-12-22 01:02:18 +00:00
e30591b584 make update_readme action
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 23m12s
2025-12-21 21:57:10 -03:00
Gitea Actions
fe849df6db Update manifest version to 7.1.5 [▶️] 2025-12-22 00:52:31 +00:00
e633457ed3 Upload files to ".gitea/workflows"
Some checks failed
Build, Push, Publish / Build & Release (push) Has been cancelled
2025-12-22 00:52:17 +00:00
Gitea Actions
e4cff69469 Update manifest version to 7.1.4 [▶️] 2025-12-22 00:28:43 +00:00
c24cf70d77 Update README.md
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 23m15s
2025-12-22 00:23:28 +00:00
Gitea Actions
e817dfe30c Update manifest version to 7.1.3 [▶️] 2025-12-22 00:15:23 +00:00
e05fa1cab6 fix .zip release
Some checks failed
Build, Push, Publish / Build & Release (push) Has been cancelled
2025-12-21 21:09:53 -03:00
Gitea Actions
7338210bcf Update manifest version to 7.1.2 [▶️] 2025-12-22 00:02:07 +00:00
6408e0c923 update release_build to greate zip file on releases
Some checks failed
Build, Push, Publish / Build & Release (push) Has been cancelled
2025-12-21 21:01:44 -03:00
Gitea Actions
4131b1dd1c Update manifest version to 7.1.1 [▶️] 2025-12-21 23:13:46 +00:00
a2feef4c08 fix addming manager to link
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 23m3s
2025-12-21 20:13:20 -03:00
f3743699a2 fix admin not show all admin users 2025-12-21 20:10:34 -03:00
Gitea Actions
e6160a4d12 Update manifest version to 7.1.0 [▶️] 2025-12-21 22:45:45 +00:00
4374f5e3cd add manage users
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 23m35s
2025-12-21 19:45:17 -03:00
Gitea Actions
212d43d145 Update manifest version to 7.0.1 [▶️] 2025-12-17 18:21:40 +00:00
3045c2df3d Merge branch 'main' of https://git.icc.gg/ivancarlos/bundledcmdb
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 24m18s
2025-12-17 15:21:10 -03:00
6d5524a215 fix export excel 2025-12-17 15:20:51 -03:00
Gitea Actions
380422d230 Update manifest version to 7.0.0 [▶️] 2025-12-10 01:33:40 +00:00
e5ea38c973 refactor to php composer
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 23m5s
2025-12-09 22:33:15 -03:00
Gitea Actions
5643e77f0f Update manifest version to 6.1.0 [▶️] 2025-12-10 00:18:53 +00:00
1e95a3cf07 phar
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 22m31s
2025-12-09 21:18:18 -03:00
Gitea Actions
e6779edec7 Update AWS SDK PHAR [▶️] 2025-12-10 00:08:02 +00:00
1f18de7750 phar
All checks were successful
Build, Push, Publish / Build & Release (push) Successful in 9s
2025-12-09 21:06:35 -03:00
9710dc1433 Merge branch 'main' of https://git.icc.gg/ivancarlos/bundledcmdb
Some checks failed
Build, Push, Publish / Build & Release (push) Has been cancelled
2025-12-09 21:01:18 -03:00
b3e70bcdf8 wrong repo 2025-12-09 21:00:59 -03:00
11 changed files with 336 additions and 89 deletions

View File

@@ -6,7 +6,7 @@ on:
- main
workflow_dispatch:
schedule:
- cron: '28 5 * * *'
- cron: "28 5 * * *"
# workflow_run support in Gitea can be tricky, keeping it but might need adjustment
workflow_run:
workflows: ["Sync Repo"]
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
permissions:
contents: write
packages: write
@@ -139,7 +139,7 @@ jobs:
LATEST_RELEASE_TAG=$(curl -sL -H "Accept: application/json" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"${{ gitea.api_url }}/repos/${{ gitea.repository }}/releases/latest" | jq -r .tag_name)
if [ -z "$LATEST_RELEASE_TAG" ] || [ "$LATEST_RELEASE_TAG" = "null" ]; then
LATEST_RELEASE_TAG="v1.0.0"
fi
@@ -245,7 +245,7 @@ jobs:
AUTHOR="Ivan Carlos"
VERSION_FILE="manifest.json"
UPSTREAM_SHA="${{ steps.check_upstream.outputs.upstream_sha }}"
if [ -f "$VERSION_FILE" ]; then
jq --arg v "$VERSION" \
--arg a "$AUTHOR" \
@@ -265,6 +265,11 @@ jobs:
git commit -m "Update manifest version to ${{ steps.version.outputs.VERSION }} [▶️]" || echo "Nothing to commit"
git push origin main
- name: 🛠 Install zip
if: steps.check_commits.outputs.commit_count != '0'
run: |
apt-get update && apt-get install -y zip
- name: 📦 Create ZIP package (excluding certain files)
if: steps.check_commits.outputs.commit_count != '0'
run: |
@@ -279,11 +284,11 @@ jobs:
run: |
TAG_NAME="v${{ steps.version.outputs.VERSION }}"
RELEASE_NAME="${{ steps.version.outputs.REPO_NAME }} v${{ steps.version.outputs.VERSION }}"
# Construct Markdown body safely using env var
# We use printf to avoid interpreting backslashes in the file list
BODY=$(printf "### Changelog\nFiles changed in this release:\n%s" "$CHANGELOG_LIST")
# Create JSON payload using jq
jq -n \
--arg tag_name "$TAG_NAME" \
@@ -299,13 +304,13 @@ jobs:
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/json" \
-d @release_payload.json > api_response.json
echo "DEBUG: API Response:"
cat api_response.json || true
RELEASE_ID=$(jq -r .id api_response.json)
echo "RELEASE_ID=$RELEASE_ID" >> "$GITHUB_OUTPUT"
if [ "$RELEASE_ID" == "null" ] || [ -z "$RELEASE_ID" ]; then
echo "Failed to create release. Response content:"
cat api_response.json
@@ -318,19 +323,18 @@ jobs:
RELEASE_ID="${{ steps.create_release.outputs.RELEASE_ID }}"
ZIP_NAME="${{ steps.version.outputs.ZIP_NAME }}"
FILE_PATH="./$ZIP_NAME"
curl -s -X POST "${{ gitea.api_url }}/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets" \
curl --fail -s -X POST "${{ gitea.api_url }}/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets?name=$ZIP_NAME" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-H "Content-Type: application/zip" \
--data-binary @"$FILE_PATH" \
-o /dev/null
--data-binary @"$FILE_PATH"
# ----- Docker steps -----
- name: Clone Upstream Code (if needed)
if: steps.check_commits.outputs.commit_count != '0' && (steps.check_upstream.outputs.upstream_needs_update == 'true' || steps.check_upstream.outputs.repo_url != '')
run: |
rm -rf upstream_src
git clone --depth 1 --branch ${{ steps.check_upstream.outputs.repo_branch }} ${{ steps.check_upstream.outputs.repo_url }} upstream_src
rm -rf upstream_src
git clone --depth 1 --branch ${{ steps.check_upstream.outputs.repo_branch }} ${{ steps.check_upstream.outputs.repo_url }} upstream_src
- name: 🔍 Check if Dockerfile exists
if: steps.check_commits.outputs.commit_count != '0' || steps.check_upstream.outputs.upstream_needs_update == 'true'

View File

@@ -1,45 +0,0 @@
name: Update AWS SDK PHAR
on:
workflow_dispatch:
schedule:
- cron: '34 3 * * *' # 03:34 UTC == 00:34 BRT
permissions:
contents: write
jobs:
download-aws-sdk:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
permissions:
contents: write
actions: write # needed to dispatch another workflow
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download AWS SDK PHAR
run: |
mkdir -p vendor
wget https://github.com/aws/aws-sdk-php/releases/latest/download/aws.phar -O vendor/aws.phar
- name: Commit and push changes
id: commit_step
run: |
git config --global --add safe.directory '*'
git config user.name "Gitea Actions"
git config user.email "actions@git.icc.gg"
git add vendor/aws.phar
# If there are changes, commit & push; set output flag accordingly
if git diff --quiet && git diff --staged --quiet; then
echo "No changes to commit"
echo "changes_committed=false" >> $GITHUB_OUTPUT
else
git commit -m "Update AWS SDK PHAR [▶️]"
git push origin HEAD:main
echo "changes_committed=true" >> $GITHUB_OUTPUT
fi

View File

@@ -0,0 +1,60 @@
name: Update README
# Allow Gitea Actions to commit and push changes
permissions:
contents: write
on:
workflow_dispatch:
schedule:
- cron: "0 4 * * *" # Every day at 4 AM UTC
jobs:
update-readme:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
env:
SOURCE_REPO: ivancarlos/.gitea
SOURCE_BRANCH: main
steps:
- name: Checkout current repository
uses: actions/checkout@v4
- name: Checkout source README template
uses: actions/checkout@v4
with:
repository: ${{ env.SOURCE_REPO }}
ref: ${{ env.SOURCE_BRANCH }}
token: ${{ secrets.CR_PAT }}
path: source_readme
- name: Update README.md (footer only)
run: |
set -e
# --- Extract footer block from source (everything from <!-- footer --> onward) ---
FOOTER=$(awk '/<!-- footer -->/{flag=1}flag' source_readme/README.md)
# --- Replace everything after <!-- footer --> with FOOTER ---
awk -v footer="$FOOTER" '
/<!-- footer -->/ {
print footer
found=1
exit
}
{ print }
' README.md > README.tmp && mv README.tmp README.md
- name: Remove source_readme from git index
run: rm -rf source_readme
- name: Commit and push changes
run: |
git config user.name "Gitea Actions"
git config user.email "actions@git.icc.gg"
git add README.md
git commit -m "Sync README from template [▶️]" || echo "Nothing to commit"
git push origin ${{ github.ref_name }}

View File

@@ -4,7 +4,7 @@ COPY composer.json composer.json
# COPY composer.lock composer.lock # No lock file yet
COPY auth_keycloak.php auth_keycloak.php
COPY s3_client.php s3_client.php
RUN composer install --no-dev --ignore-platform-reqs --no-scripts --prefer-dist
RUN export COMPOSER_PROCESS_TIMEOUT=2000 && composer install --no-dev --ignore-platform-reqs --no-scripts --prefer-dist
# Stage 2: Final image
FROM php:8.4-fpm-alpine
@@ -16,6 +16,8 @@ RUN apk add --no-cache --update nginx \
# Copy dependencies from vendor stage
COPY --from=vendor /app/vendor /var/www/html/vendor
# Copy aws.phar
# aws.phar is now installed via composer
# Copy application code
COPY . /var/www/html/

View File

@@ -1,19 +1,6 @@
# Bundled CMDB
Small CMDB project that uses ESET data sent to database for asset management, uses Keycloak as SSO provider for user authentication, S3 for file submission and access related to each asset
<!-- buttons -->
[![Stars](https://img.shields.io/github/stars/ivancarlosti/bundledcmdb?label=⭐%20Stars&color=gold&style=flat)](https://github.com/ivancarlosti/bundledcmdb/stargazers)
[![Watchers](https://img.shields.io/github/watchers/ivancarlosti/bundledcmdb?label=Watchers&style=flat&color=red)](https://github.com/sponsors/ivancarlosti)
[![Forks](https://img.shields.io/github/forks/ivancarlosti/bundledcmdb?label=Forks&style=flat&color=ff69b4)](https://github.com/sponsors/ivancarlosti)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/ivancarlosti/bundledcmdb?label=Activity)](https://github.com/ivancarlosti/bundledcmdb/pulse)
[![GitHub Issues](https://img.shields.io/github/issues/ivancarlosti/bundledcmdb?label=Issues&color=orange)](https://github.com/ivancarlosti/bundledcmdb/issues)
[![License](https://img.shields.io/github/license/ivancarlosti/bundledcmdb?label=License)](LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/ivancarlosti/bundledcmdb?label=Last%20Commit)](https://github.com/ivancarlosti/bundledcmdb/commits)
[![Security](https://img.shields.io/badge/Security-View%20Here-purple)](https://github.com/ivancarlosti/bundledcmdb/security)
[![Code of Conduct](https://img.shields.io/badge/Code%20of%20Conduct-2.1-4baaaa)](https://github.com/ivancarlosti/bundledcmdb?tab=coc-ov-file)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/ivancarlosti?label=GitHub%20Sponsors&color=ffc0cb)][sponsor]
<!-- endbuttons -->
## Requirement:
* [Docker Compose](https://docs.docker.com/engine/install/)

View File

@@ -4,10 +4,10 @@
"type": "project",
"require": {
"php": "^8.2",
"aws/aws-sdk-php": "^3.300",
"ext-pdo": "*",
"ext-curl": "*",
"ext-json": "*"
"ext-json": "*",
"aws/aws-sdk-php": "^3.0"
},
"autoload": {
"classmap": [
@@ -15,4 +15,4 @@
"s3_client.php"
]
}
}
}

View File

@@ -1,9 +0,0 @@
<?php
require 'config.php';
try {
$pdo = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4", DB_USER, DB_PASS);
$stmt = $pdo->query("DESCRIBE users");
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}

View File

@@ -1,4 +1,4 @@
{
"version": "6.0.0",
"version": "7.1.7",
"author": "Ivan Carlos"
}

View File

@@ -140,7 +140,7 @@ $output = fopen('php://output', 'w');
fwrite($output, "\xEF\xBB\xBF");
// Write CSV header row
fputcsv($output, $columns_to_export);
fputcsv($output, $columns_to_export, ",", "\"", "\\");
// Write all rows
foreach ($allRows as $row) {
@@ -152,7 +152,7 @@ foreach ($allRows as $row) {
}
$exportRow[] = $val;
}
fputcsv($output, $exportRow);
fputcsv($output, $exportRow, ",", "\"", "\\");
}
fclose($output);

View File

@@ -247,6 +247,11 @@ function sort_arrow($col, $current_by, $current_dir) {
<?php endif; ?>
<button type="submit" class="export-btn">Export to Excel</button>
</form>
<?php if ($role === 'superadmin'): ?>
<form method="get" action="manage_permissions.php" style="margin: 0;">
<button type="submit" class="export-btn" style="background-color: #2196F3;">Manage Permissions</button>
</form>
<?php endif; ?>
<div class="header-links">
<form method="post" action="logout.php" style="display:inline;">
<button type="submit">Logout</button>

View File

@@ -0,0 +1,243 @@
<?php
// manage_permissions.php
session_start();
require_once '../config.php';
// Security check: Only SuperAdmins allowed
$role = $_SESSION['role'] ?? 'user';
if ($role !== 'superadmin') {
die('Access Denied: You must be a SuperAdmin to view this page.');
}
// Helper: Escape output
function escape($text) {
return htmlspecialchars((string)$text, ENT_QUOTES, 'UTF-8');
}
// DB Connection
try {
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
DB_USER,
DB_PASS,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
die("DB Connection failed: " . $e->getMessage());
}
$message = '';
$messageType = ''; // 'success' or 'error'
// Handle POST actions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'add' || $action === 'update') {
$email = $_POST['email'] ?? '';
$newRole = $_POST['role_to_set'] ?? '';
if ($email && in_array($newRole, ['admin', 'superadmin', 'manager'])) {
// Update user role
$stmt = $pdo->prepare("UPDATE users SET role = :role WHERE email = :email");
$success = $stmt->execute([':role' => $newRole, ':email' => $email]);
if ($success && $stmt->rowCount() > 0) {
$message = "Successfully updated permission for " . escape($email);
$messageType = 'success';
} elseif ($success) {
$message = "User " . escape($email) . " already has that role or does not exist.";
$messageType = 'info';
} else {
$message = "Failed to update permission.";
$messageType = 'error';
}
}
} elseif ($action === 'remove') {
$email = $_POST['email'] ?? '';
// Prevent self-removal if validation needed, but usually SuperAdmin can remove themselves if not careful.
// Let's just allow it or maybe warn. For now allow.
if ($email === $_SESSION['user_email']) {
$message = "You cannot remove your own SuperAdmin status from here.";
$messageType = 'error';
} else {
$stmt = $pdo->prepare("UPDATE users SET role = 'user' WHERE email = :email");
$success = $stmt->execute([':email' => $email]);
if ($success) {
$message = "Removed admin rights from " . escape($email);
$messageType = 'success';
}
}
}
}
// Fetch Admins and SuperAdmins
$stmt = $pdo->query("SELECT * FROM users WHERE LOWER(TRIM(role)) IN ('admin', 'superadmin', 'manager') ORDER BY role DESC, email ASC");
$admins = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch All Users for Dropdown
$stmt = $pdo->query("SELECT email FROM users ORDER BY email ASC");
$allUsers = $stmt->fetchAll(PDO::FETCH_COLUMN);
?>
<!DOCTYPE html>
<html>
<head>
<title>Manage Permissions</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<style>
.container {
max-width: 900px;
margin: 20px auto;
padding: 20px;
background: #fff;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
border-bottom: 2px solid #eee;
padding-bottom: 1rem;
}
.message {
padding: 10px;
margin-bottom: 20px;
border-radius: 4px;
}
.message.success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.message.error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
.message.info { background: #cce5ff; color: #004085; border: 1px solid #b8daff; }
.section {
margin-bottom: 2rem;
padding: 1.5rem;
background: #f8f9fa;
border-radius: 4px;
border: 1px solid #dee2e6;
}
.section h3 { margin-top: 0; }
table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }
th { background: #f1f1f1; }
.role-badge {
padding: 4px 8px;
border-radius: 12px;
font-size: 0.85em;
font-weight: bold;
}
.role-superadmin { background: #6f42c1; color: white; }
.role-admin { background: #28a745; color: white; }
.role-manager { background: #17a2b8; color: white; }
.btn-remove {
background: #dc3545;
color: white;
border: none;
padding: 5px 10px;
border-radius: 3px;
cursor: pointer;
}
.btn-add {
background: #007bff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
select, input { padding: 8px; border: 1px solid #ced4da; border-radius: 4px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h2>Permission Management</h2>
<a href="main.php" class="btn-add" style="background: #6c757d; text-decoration: none;">&laquo; Back to Dashboard</a>
</div>
<?php if ($message): ?>
<div class="message <?php echo $messageType; ?>">
<?php echo escape($message); ?>
</div>
<?php endif; ?>
<!-- Add New Section -->
<div class="section">
<h3>Grant Permissions</h3>
<p>Select a user to promote to Admin or SuperAdmin status.</p>
<form method="post" style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
<input type="hidden" name="action" value="add">
<label for="email">User:</label>
<select name="email" id="email" required style="min-width: 200px;">
<option value="">-- Select User --</option>
<?php foreach ($allUsers as $uEmail): ?>
<option value="<?php echo escape($uEmail); ?>">
<?php echo escape($uEmail); ?>
</option>
<?php endforeach; ?>
</select>
<label for="role">Role:</label>
<select name="role_to_set" id="role" required>
<option value="manager">Manager</option>
<option value="admin">Admin</option>
<option value="superadmin">SuperAdmin</option>
</select>
<button type="submit" class="btn-add">Grant Permission</button>
</form>
</div>
<!-- List Section -->
<div class="section" style="background: white; border: none; padding: 0;">
<h3>Current Admins & SuperAdmins</h3>
<table>
<thead>
<tr>
<th>Email</th>
<th>Company</th>
<th>Current Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($admins)): ?>
<tr><td colspan="4">No admins found.</td></tr>
<?php else: ?>
<?php foreach ($admins as $admin): ?>
<tr>
<td><?php echo escape($admin['email']); ?></td>
<td><?php echo escape($admin['company']); ?></td>
<td>
<span class="role-badge role-<?php echo escape($admin['role']); ?>">
<?php echo strtoupper(escape($admin['role'])); ?>
</span>
</td>
<td>
<?php if ($admin['email'] === $_SESSION['user_email']): ?>
<span style="color: #6c757d; font-style: italic;">(You)</span>
<?php else: ?>
<form method="post" style="display:inline;" onsubmit="return confirm('Are you sure you want to remove admin rights from this user?');">
<input type="hidden" name="action" value="remove">
<input type="hidden" name="email" value="<?php echo escape($admin['email']); ?>">
<button type="submit" class="btn-remove">Remove</button>
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</body>
</html>