mj add another admin
This commit is contained in:
7
app.py
7
app.py
@@ -21,17 +21,18 @@ login_manager.login_view = 'auth.login'
|
||||
login_manager.login_message = 'Παρακαλώ συνδεθείτε για να συνεχίσετε.'
|
||||
|
||||
class User(UserMixin):
|
||||
def __init__(self, id, username):
|
||||
def __init__(self, id, username, clan_id):
|
||||
self.id = id
|
||||
self.username = username
|
||||
self.clan_id = clan_id
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
conn = get_db()
|
||||
row = conn.execute('SELECT id, username FROM users WHERE id = ?', (user_id,)).fetchone()
|
||||
row = conn.execute('SELECT id, username, clan_id FROM users WHERE id = ?', (user_id,)).fetchone()
|
||||
conn.close()
|
||||
if row:
|
||||
return User(row['id'], row['username'])
|
||||
return User(row['id'], row['username'], row['clan_id'])
|
||||
return None
|
||||
|
||||
# Make current_user available in all templates
|
||||
|
||||
13
db.py
13
db.py
@@ -77,6 +77,7 @@ def init_db():
|
||||
'ALTER TABLE commands ADD COLUMN player_id TEXT',
|
||||
'ALTER TABLE farm_settings ADD COLUMN bandit_camp_enabled INTEGER NOT NULL DEFAULT 0',
|
||||
"ALTER TABLE clan_members ADD COLUMN features TEXT NOT NULL DEFAULT 'farm,admin'",
|
||||
'ALTER TABLE users ADD COLUMN clan_id INTEGER REFERENCES clans(id)',
|
||||
]:
|
||||
try:
|
||||
c.execute(_col)
|
||||
@@ -89,6 +90,7 @@ def init_db():
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
clan_id INTEGER REFERENCES clans(id),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)
|
||||
''')
|
||||
@@ -111,11 +113,22 @@ def init_db():
|
||||
clan_id INTEGER NOT NULL REFERENCES clans(id),
|
||||
player_id TEXT NOT NULL,
|
||||
player_name TEXT,
|
||||
features TEXT NOT NULL DEFAULT 'farm,admin',
|
||||
joined_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(clan_id, player_id)
|
||||
)
|
||||
''')
|
||||
|
||||
# Migration: Auto-assign existing users to their clan_id if they are the owner
|
||||
try:
|
||||
c.execute('''
|
||||
UPDATE users
|
||||
SET clan_id = (SELECT id FROM clans WHERE owner_id = users.id)
|
||||
WHERE clan_id IS NULL AND EXISTS (SELECT 1 FROM clans WHERE owner_id = users.id)
|
||||
''')
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ auth = Blueprint('auth', __name__)
|
||||
# ------------------------------------------------------------------
|
||||
def _make_user(row):
|
||||
from app import User
|
||||
return User(row['id'], row['username'])
|
||||
return User(row['id'], row['username'], row['clan_id'])
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@@ -30,7 +30,7 @@ def login():
|
||||
|
||||
conn = get_db()
|
||||
row = conn.execute(
|
||||
'SELECT id, username, password_hash FROM users WHERE username = ?', (username,)
|
||||
'SELECT id, username, password_hash, clan_id FROM users WHERE username = ?', (username,)
|
||||
).fetchone()
|
||||
conn.close()
|
||||
|
||||
@@ -80,7 +80,7 @@ def register():
|
||||
)
|
||||
conn.commit()
|
||||
row = conn.execute(
|
||||
'SELECT id, username, password_hash FROM users WHERE username = ?', (username,)
|
||||
'SELECT id, username, password_hash, clan_id FROM users WHERE username = ?', (username,)
|
||||
).fetchone()
|
||||
conn.close()
|
||||
user = _make_user(row)
|
||||
@@ -108,9 +108,20 @@ def logout():
|
||||
def options():
|
||||
conn = get_db()
|
||||
|
||||
clan = conn.execute(
|
||||
'SELECT * FROM clans WHERE owner_id = ?', (current_user.id,)
|
||||
).fetchone()
|
||||
# Load clan based on current user's clan_id
|
||||
clan = None
|
||||
if current_user.clan_id:
|
||||
clan = conn.execute(
|
||||
'SELECT * FROM clans WHERE id = ?', (current_user.clan_id,)
|
||||
).fetchone()
|
||||
|
||||
# Fetch website admins (users belonging to this clan other than current user)
|
||||
admins = []
|
||||
if clan and clan['owner_id'] == current_user.id:
|
||||
admins = conn.execute(
|
||||
'SELECT id, username, created_at FROM users WHERE clan_id = ? AND id != ? ORDER BY created_at ASC',
|
||||
(clan['id'], current_user.id)
|
||||
).fetchall()
|
||||
|
||||
members = []
|
||||
if clan:
|
||||
@@ -146,7 +157,7 @@ def options():
|
||||
})
|
||||
|
||||
conn.close()
|
||||
return render_template('options.html', clan=clan, members=members)
|
||||
return render_template('options.html', clan=clan, members=members, admins=admins)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@@ -166,12 +177,17 @@ def create_clan():
|
||||
|
||||
if not existing:
|
||||
key = generate_clan_key()
|
||||
conn.execute(
|
||||
cursor = conn.execute(
|
||||
'INSERT INTO clans (owner_id, name, clan_key) VALUES (?, ?, ?)',
|
||||
(current_user.id, clan_name, key)
|
||||
)
|
||||
clan_id = cursor.lastrowid
|
||||
conn.execute('UPDATE users SET clan_id = ? WHERE id = ?', (clan_id, current_user.id))
|
||||
conn.commit()
|
||||
|
||||
# Update the current_user object dynamically to reflect the new clan_id without re-login
|
||||
current_user.clan_id = clan_id
|
||||
|
||||
conn.close()
|
||||
return redirect(url_for('auth.options'))
|
||||
|
||||
@@ -233,3 +249,55 @@ def update_member_features(player_id):
|
||||
conn.close()
|
||||
return redirect(url_for('auth.options'))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# POST /auth/clan/add-admin
|
||||
# ------------------------------------------------------------------
|
||||
@auth.route('/auth/clan/add-admin', methods=['POST'])
|
||||
@login_required
|
||||
def add_admin():
|
||||
username = request.form.get('admin_username', '').strip()
|
||||
if not username:
|
||||
return redirect(url_for('auth.options'))
|
||||
|
||||
conn = get_db()
|
||||
clan = conn.execute(
|
||||
'SELECT id FROM clans WHERE owner_id = ?', (current_user.id,)
|
||||
).fetchone()
|
||||
|
||||
if clan:
|
||||
# Check if user exists
|
||||
user = conn.execute('SELECT id, clan_id FROM users WHERE username = ?', (username,)).fetchone()
|
||||
if user:
|
||||
# If user already belongs to a clan, we could show an error, but let's just overwrite for now
|
||||
# or maybe only if clan_id is NULL
|
||||
conn.execute('UPDATE users SET clan_id = ? WHERE id = ?', (clan['id'], user['id']))
|
||||
conn.commit()
|
||||
flash(f"Ο χρήστης {username} προστέθηκε ως διαχειριστής.", "success")
|
||||
else:
|
||||
flash(f"Ο χρήστης {username} δεν βρέθηκε.", "error")
|
||||
|
||||
conn.close()
|
||||
return redirect(url_for('auth.options'))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# POST /auth/clan/remove-admin/<admin_id>
|
||||
# ------------------------------------------------------------------
|
||||
@auth.route('/auth/clan/remove-admin/<int:admin_id>', methods=['POST'])
|
||||
@login_required
|
||||
def remove_admin(admin_id):
|
||||
conn = get_db()
|
||||
clan = conn.execute(
|
||||
'SELECT id FROM clans WHERE owner_id = ?', (current_user.id,)
|
||||
).fetchone()
|
||||
|
||||
if clan:
|
||||
conn.execute('UPDATE users SET clan_id = NULL WHERE id = ? AND clan_id = ?', (admin_id, clan['id']))
|
||||
conn.commit()
|
||||
flash("Ο διαχειριστής αφαιρέθηκε.", "success")
|
||||
|
||||
conn.close()
|
||||
return redirect(url_for('auth.options'))
|
||||
|
||||
|
||||
|
||||
@@ -16,18 +16,14 @@ dashboard = Blueprint('dashboard', __name__)
|
||||
def index():
|
||||
conn = get_db()
|
||||
|
||||
# Get the logged-in user's clan
|
||||
clan = conn.execute(
|
||||
'SELECT id FROM clans WHERE owner_id = ?', (current_user.id,)
|
||||
).fetchone()
|
||||
# Get the clan the logged-in user belongs to
|
||||
clan_id = current_user.clan_id
|
||||
|
||||
if not clan:
|
||||
# User has no clan yet — send them to options to create one
|
||||
if not clan_id:
|
||||
# User has no clan yet — send them to options to create/join one
|
||||
conn.close()
|
||||
return render_template('index.html', players=[], no_clan=True)
|
||||
|
||||
clan_id = clan['id']
|
||||
|
||||
# Only fetch players that are members of this clan
|
||||
rows = conn.execute('''
|
||||
SELECT ts.player, ts.player_id, MAX(ts.updated_at) as last_seen, MAX(ts.world_id) as world_id
|
||||
|
||||
@@ -175,7 +175,18 @@
|
||||
<div class="page-title">Ρυθμίσεις Clan</div>
|
||||
<div class="page-subtitle">Διαχείριση της ομάδας σας και του κλειδιού πρόσβασης</div>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="warn-box" style="margin-bottom: 20px; color: {% if category == 'error' %}#f85149{% else %}#3fb950{% endif %}; border-color: {% if category == 'error' %}rgba(248,81,73,0.3){% else %}rgba(63,185,80,0.3){% endif %}; background: {% if category == 'error' %}rgba(248,81,73,0.1){% else %}rgba(63,185,80,0.1){% endif %};">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
{% if clan %}
|
||||
{% if clan.owner_id == current_user.id %}
|
||||
<!-- ===================== Clan Key Section ===================== -->
|
||||
<div class="card">
|
||||
<div class="card-title">🔑 Clan Key</div>
|
||||
@@ -195,6 +206,49 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- ===================== Website Admins Section ===================== -->
|
||||
<div class="card">
|
||||
<div class="card-title">👨💻 Website Admins</div>
|
||||
<p style="color:#8b949e; font-size:0.875rem; margin-bottom:14px;">
|
||||
Προσθέστε το username άλλων παικτών που έχουν ήδη εγγραφεί στο site για να τους δώσετε πρόσβαση στο dashboard σας.
|
||||
</p>
|
||||
<form method="POST" action="/auth/clan/add-admin" class="inline-form" style="margin-bottom: 20px;">
|
||||
<input type="text" name="admin_username" placeholder="π.χ. player123" required>
|
||||
<button type="submit" class="btn-primary">Προσθήκη Admin</button>
|
||||
</form>
|
||||
|
||||
{% if admins %}
|
||||
<table class="members-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Admin Username</th>
|
||||
<th>Ημερομηνία Προσθήκης</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for a in admins %}
|
||||
<tr>
|
||||
<td><div class="player-name">{{ a.username }}</div></td>
|
||||
<td style="color:#8b949e; font-size:0.8rem;">{{ a.created_at[:10] }}</td>
|
||||
<td style="text-align:right;">
|
||||
<form method="POST" action="/auth/clan/remove-admin/{{ a.id }}" onsubmit="return confirm('Αφαίρεση του admin {{ a.username }}?');">
|
||||
<button type="submit" class="btn-danger">Αφαίρεση</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="empty-state" style="padding: 16px 0;">
|
||||
Δεν έχετε προσθέσει κανέναν website admin ακόμη.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<!-- ===================== Members Section ===================== -->
|
||||
<div class="card">
|
||||
<div class="card-title">👥 Μέλη Clan — {{ clan.name }}</div>
|
||||
@@ -224,6 +278,7 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if clan.owner_id == current_user.id %}
|
||||
<form method="POST" action="/auth/clan/update-features/{{ m.player_id }}" style="display:inline;">
|
||||
<div class="toggle-group">
|
||||
<label class="toggle-label">
|
||||
@@ -234,13 +289,21 @@
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="toggle-group" style="opacity: 0.8;">
|
||||
<span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_farm else '#30363d' }}; color: {{ '#3fb950' if m.feat_farm else '#8b949e' }};">🌾 Farm</span>
|
||||
<span class="toggle-label" style="cursor:default; border-color: {{ '#3fb950' if m.feat_admin else '#30363d' }}; color: {{ '#3fb950' if m.feat_admin else '#8b949e' }};">🏛 Admin</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="color:#8b949e; font-size:0.8rem;">{{ m.joined_at }}</td>
|
||||
<td style="text-align:right;">
|
||||
{% if clan.owner_id == current_user.id %}
|
||||
<form method="POST" action="/auth/clan/remove-member/{{ m.player_id }}"
|
||||
onsubmit="return confirm('Αφαίρεση παίκτη {{ m.player_name }}?');">
|
||||
<button type="submit" class="btn-danger">Αφαίρεση</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user