-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathmain.py
More file actions
194 lines (150 loc) · 5.79 KB
/
main.py
File metadata and controls
194 lines (150 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
from datetime import datetime
import discord
import ezcord
import uvicorn
from discord.ext.ipc import Client
from fastapi import Cookie, FastAPI, HTTPException, Request
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from contextlib import asynccontextmanager
from backend import DiscordAuth, db, feature_db
# Hier die Daten aus dem Developer-Portal einfügen
CLIENT_ID = 123456789
CLIENT_SECRET = ""
REDIRECT_URI = "http://localhost:8000/callback"
LOGIN_URL = ""
INVITE_LINK = ""
@asynccontextmanager
async def on_startup(app: FastAPI):
await api.setup()
await db.setup()
await feature_db.setup()
yield
await api.close()
# Hier kann noch selbst eine Methode, die je nach Datenbank variiert, hinzugefügt werden, um die Datenbank zu "schließen"
app = FastAPI(lifespan=on_startup)
app.mount("/static", StaticFiles(directory="frontend/static"), name="static")
templates = Jinja2Templates(directory="frontend")
ipc = Client(secret_key="keks")
api = DiscordAuth(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI)
@app.get("/")
async def home(request: Request):
session_id = request.cookies.get("session_id")
if session_id and await db.get_session(session_id):
return RedirectResponse(url="/guilds")
guild_count = await ipc.request("guild_count")
return templates.TemplateResponse(
"index.html",
{
"request": request,
"count": guild_count.response,
"login_url": LOGIN_URL
}
)
@app.get("/callback")
async def callback(code: str):
data = {
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"grant_type": "authorization_code",
"code": code,
"redirect_uri": REDIRECT_URI,
}
result = await api.get_token_response(data)
if result is None:
raise HTTPException(status_code=401, detail="Invalid Auth Code")
token, refresh_token, expires_in = result
user = await api.get_user(token)
user_id = user.get("id")
session_id = await db.add_session(token, refresh_token, expires_in, user_id)
response = RedirectResponse(url="/guilds")
response.set_cookie(key="session_id", value=session_id, httponly=True)
return response
@app.get("/guilds")
async def guilds(request: Request):
session_id = request.cookies.get("session_id")
session = await db.get_session(session_id)
if not session_id or not session:
raise HTTPException(status_code=401, detail="no auth")
token, refresh_token, token_expires_at = session
user = await api.get_user(token)
if datetime.now() > token_expires_at or user.get("code") == 0:
if await api.reload(session_id, refresh_token):
RedirectResponse(url="/guilds")
else:
RedirectResponse(url="/logout")
if "id" not in user:
return RedirectResponse(url="/logout")
user_guilds = await api.get_guilds(token)
bot_guilds = await ipc.request("bot_guilds")
perms = []
for guild in user_guilds:
if guild["id"] in bot_guilds.response["data"]:
guild["url"] = "/server/" + str(guild["id"])
else:
guild["url"] = INVITE_LINK + f"&guild_id={guild['id']}"
if guild["icon"]:
guild["icon"] = "https://cdn.discordapp.com/icons/" + guild["id"] + "/" + guild["icon"]
else:
guild["icon"] = ezcord.random_avatar()
is_admin = discord.Permissions(int(guild["permissions"])).administrator
if is_admin or guild["owner"]:
perms.append(guild)
return templates.TemplateResponse(
"guilds.html",
{
"request": request,
"global_name": user["global_name"],
"guilds": perms
}
)
@app.get("/server/{guild_id}")
async def server(request: Request, guild_id: int):
session_id = request.cookies.get("session_id")
if not session_id or not await db.get_session(session_id):
raise HTTPException(status_code=401, detail="no auth")
stats = await ipc.request("guild_stats", guild_id=guild_id)
setting = await feature_db.get_setting(guild_id, "example_feature")
if setting:
feature_txt = "Das Feature ist aktiviert"
else:
feature_txt = "Das Feature ist deaktiviert"
return templates.TemplateResponse(
"server.html",
{
"request": request,
"name": stats.response["name"],
"count": stats.response["member_count"],
"id": guild_id,
"feature": feature_txt,
},
)
@app.get("/server/{guild_id}/settings/{feature}")
async def change_settings(guild_id: int, feature: str, session_id: str = Cookie(None)):
user_id = await db.get_user_id(session_id)
if not session_id or not user_id:
raise HTTPException(status_code=401, detail="no auth")
perms = await ipc.request("check_perms", guild_id=guild_id, user_id=user_id)
if perms.response["perms"]:
await feature_db.toggle_setting(guild_id, feature)
return RedirectResponse(url="/server/" + str(guild_id))
else:
return {"error": "Du hast keinen Zugriff auf diesen Server"}
@app.get("/logout")
async def logout(session_id: str = Cookie(None)):
session = await db.get_session(session_id)
if not session_id or not session:
raise HTTPException(status_code=401, detail="no auth")
token, _, _ = session
response = RedirectResponse("/")
response.delete_cookie(key="session_id", httponly=True)
await db.delete_session(session_id)
await api.revoke_token(token)
return response
@app.exception_handler(404)
async def error_redirect(_, __):
return RedirectResponse("/")
if __name__ == "__main__":
uvicorn.run(app, host="localhost", port=8000)
# uvicorn.run("main:app", host="localhost", port=8000, reload=True)