Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added __pycache__/app.cpython-313.pyc
Binary file not shown.
11 changes: 10 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
from routes.events import events_bp
from routes.members import members_bp
from routes.projects import projects_bp
from routes.test_admin import test_bp
from routes.admin.news import admin_news_bp
from routes.admin.events import admin_events_bp
from routes.admin.projects import admin_projects_bp
from routes.admin.members import admin_members_bp

app = Flask(__name__)
app.config.from_object(Config)
Expand All @@ -14,7 +19,11 @@
app.register_blueprint(news_bp)
app.register_blueprint(members_bp)
app.register_blueprint(projects_bp)

app.register_blueprint(test_bp)
app.register_blueprint(admin_news_bp)
app.register_blueprint(admin_events_bp)
app.register_blueprint(admin_projects_bp)
app.register_blueprint(admin_members_bp)
#print(app.url_map)


Expand Down
Binary file modified instance/osc.db
Binary file not shown.
Empty file added middlewares/__init__.py
Empty file.
Binary file added middlewares/__pycache__/__init__.cpython-313.pyc
Binary file not shown.
Binary file added middlewares/__pycache__/admin.cpython-313.pyc
Binary file not shown.
Binary file added middlewares/__pycache__/auth.cpython-313.pyc
Binary file not shown.
17 changes: 17 additions & 0 deletions middlewares/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from functools import wraps
from flask import jsonify, g

def admin_required(f):
@wraps(f)
def decorated(*args, **kwargs):
user = getattr(g, "user", None)

if not user:
return jsonify({"error": "Unauthorized"}), 401

if not user.whitelisted:
return jsonify({"error": "Admin access required"}), 403

return f(*args, **kwargs)

return decorated
29 changes: 29 additions & 0 deletions middlewares/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from functools import wraps
from flask import request, jsonify, g
from models.user import User
from models.db import db

def auth_required(f):
@wraps(f)
def decorated(*args, **kwargs):
token = request.headers.get("Authorization")

if not token:
return jsonify({"error": "Authorization token missing"}), 401

# Expecting: Authorization: Bearer <token>
try:
token = token.split(" ")[1]
except IndexError:
return jsonify({"error": "Invalid token format"}), 401

# TEMP SIMPLE AUTH (replace later with JWT)
user = User.query.filter_by(username=token).first()

if not user:
return jsonify({"error": "Invalid token"}), 401

g.user = user
return f(*args, **kwargs)

return decorated
Binary file modified routes/__pycache__/events.cpython-313.pyc
Binary file not shown.
Binary file modified routes/__pycache__/news.cpython-313.pyc
Binary file not shown.
Binary file added routes/__pycache__/test_admin.cpython-313.pyc
Binary file not shown.
Binary file added routes/admin/__pycache__/events.cpython-313.pyc
Binary file not shown.
Binary file added routes/admin/__pycache__/members.cpython-313.pyc
Binary file not shown.
Binary file added routes/admin/__pycache__/news.cpython-313.pyc
Binary file not shown.
Binary file not shown.
62 changes: 62 additions & 0 deletions routes/admin/events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from flask import Blueprint, request, jsonify
from models.db import db
from models.event import Event
from middlewares.auth import auth_required
from middlewares.admin import admin_required
from datetime import datetime

admin_events_bp = Blueprint(
"admin_events",
__name__,
url_prefix="/api/admin/events"
)

# CREATE event
@admin_events_bp.route("", methods=["POST"])
@auth_required
@admin_required
def create_event():
data = request.json

event = Event(
title=data["title"],
date=datetime.fromisoformat(data["date"]),
tag=data["tag"]
)

db.session.add(event)
db.session.commit()

return jsonify({"message": "Event created", "id": event.id}), 201


# UPDATE event
@admin_events_bp.route("/<int:event_id>", methods=["PUT"])
@auth_required
@admin_required
def update_event(event_id):
event = Event.query.get_or_404(event_id)
data = request.json

event.title = data.get("title", event.title)
event.date = (
datetime.fromisoformat(data["date"])
if "date" in data else event.date
)
event.tag = data.get("tag", event.tag)

db.session.commit()
return jsonify({"message": "Event updated"})


# DELETE event
@admin_events_bp.route("/<int:event_id>", methods=["DELETE"])
@auth_required
@admin_required
def delete_event(event_id):
event = Event.query.get_or_404(event_id)

db.session.delete(event)
db.session.commit()

return jsonify({"message": "Event deleted"})
81 changes: 81 additions & 0 deletions routes/admin/members.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from flask import Blueprint, request, jsonify
from models.db import db
from models.member import Member
from models.enums import PositionEnum
from middlewares.auth import auth_required
from middlewares.admin import admin_required

admin_members_bp = Blueprint(
"admin_members",
__name__,
url_prefix="/api/admin/members"
)

# CREATE member
@admin_members_bp.route("", methods=["POST"])
@auth_required
@admin_required
def create_member():
data = request.json

position = data["position"].lower()

if position not in [p.value for p in PositionEnum]:
return jsonify({
"error": "Invalid position",
"allowed": [p.value for p in PositionEnum]
}), 400

member = Member(
name=data["name"],
department=data["department"],
position=position,
git=data.get("git"),
linkedin=data.get("linkedin"),
instagram=data.get("instagram")
)

db.session.add(member)
db.session.commit()

return jsonify({"message": "Member created", "id": member.id}), 201


# UPDATE member
@admin_members_bp.route("/<int:member_id>", methods=["PUT"])
@auth_required
@admin_required
def update_member(member_id):
member = Member.query.get_or_404(member_id)
data = request.json

if "position" in data:
pos = data["position"].lower()
if pos not in [p.value for p in PositionEnum]:
return jsonify({
"error": "Invalid position",
"allowed": [p.value for p in PositionEnum]
}), 400
member.position = pos

member.name = data.get("name", member.name)
member.department = data.get("department", member.department)
member.git = data.get("git", member.git)
member.linkedin = data.get("linkedin", member.linkedin)
member.instagram = data.get("instagram", member.instagram)

db.session.commit()
return jsonify({"message": "Member updated"})


# DELETE member
@admin_members_bp.route("/<int:member_id>", methods=["DELETE"])
@auth_required
@admin_required
def delete_member(member_id):
member = Member.query.get_or_404(member_id)

db.session.delete(member)
db.session.commit()

return jsonify({"message": "Member deleted"})
90 changes: 90 additions & 0 deletions routes/admin/news.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from flask import Blueprint, request, jsonify
from models.db import db
from models.news import News
from middlewares.auth import auth_required
from middlewares.admin import admin_required
from datetime import datetime

admin_news_bp = Blueprint("admin_news", __name__, url_prefix="/admin/news")

# ADMIN: fetch automation
@admin_news_bp.route("/fetch", methods=["POST"])
@auth_required
@admin_required
def fetch_news_admin():
scraped_news = [
{
"title": "Linux Kernel 6.10 Released(Patch 2)",
"source": "https://kernel.org/v2",
"content": "New performance improvements and bug fixes"
},
{
"title": "Python 3.13 Features",
"source": "https://python.org",
"content": "New optimizations and syntax improvements"
}
]

inserted = 0
for item in scraped_news:
if not News.query.filter_by(title=item["title"]).first():
news = News(
title=item["title"],
source=item["source"],
content=item["content"],
date=datetime.utcnow()
)
db.session.add(news)
inserted += 1

db.session.commit()
return jsonify({"message": f"{inserted} news items inserted"}), 201

# CREATE news
@admin_news_bp.route("", methods=["POST"])
@auth_required
@admin_required
def create_news():
data = request.json

news = News(
title=data.get("title"),
source=data.get("source"),
content=data.get("content")
)

db.session.add(news)
db.session.commit()

return jsonify({"message": "News created", "id": news.id}), 201


# UPDATE news
@admin_news_bp.route("/<int:news_id>", methods=["PUT"])
@auth_required
@admin_required
def update_news(news_id):
news = News.query.get_or_404(news_id)
data = request.json

news.title = data.get("title", news.title)
news.source = data.get("source", news.source)
news.content = data.get("content", news.content)

db.session.commit()

return jsonify({"message": "News updated successfully"})



# DELETE news
@admin_news_bp.route("/<int:news_id>", methods=["DELETE"])
@auth_required
@admin_required
def delete_news(news_id):
news = News.query.get_or_404(news_id)

db.session.delete(news)
db.session.commit()

return jsonify({"message": "News deleted"})
64 changes: 64 additions & 0 deletions routes/admin/projects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from flask import Blueprint, request, jsonify
from models.db import db
from models.project import Project
from middlewares.auth import auth_required
from middlewares.admin import admin_required
from datetime import datetime

admin_projects_bp = Blueprint(
"admin_projects",
__name__,
url_prefix="/api/admin/projects"
)

# CREATE project
@admin_projects_bp.route("", methods=["POST"])
@auth_required
@admin_required
def create_project():
data = request.json

project = Project(
title=data["title"],
git=data["git"],
contributors=data["contributors"],
date=datetime.fromisoformat(data["date"])
)

db.session.add(project)
db.session.commit()

return jsonify({"message": "Project created", "id": project.id}), 201


# UPDATE project
@admin_projects_bp.route("/<int:project_id>", methods=["PUT"])
@auth_required
@admin_required
def update_project(project_id):
project = Project.query.get_or_404(project_id)
data = request.json

project.title = data.get("title", project.title)
project.git = data.get("git", project.git)
project.contributors = data.get("contributors", project.contributors)
project.date = (
datetime.fromisoformat(data["date"])
if "date" in data else project.date
)

db.session.commit()
return jsonify({"message": "Project updated"})


# DELETE project
@admin_projects_bp.route("/<int:project_id>", methods=["DELETE"])
@auth_required
@admin_required
def delete_project(project_id):
project = Project.query.get_or_404(project_id)

db.session.delete(project)
db.session.commit()

return jsonify({"message": "Project deleted"})
Empty file added routes/auth.py
Empty file.
16 changes: 0 additions & 16 deletions routes/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,3 @@ def get_events():
for e in events
])

#post for create admin

@events_bp.route("", methods=["POST"])
def create_event():
data = request.get_json()

event = Event(
title=data["title"],
date=datetime.fromisoformat(data["date"]),
tag=data["tag"]
)

db.session.add(event)
db.session.commit()

return {"message": "Event created"}, 201
Loading