From 095a87a7a51b364001547b863c2fc4278bb553d9 Mon Sep 17 00:00:00 2001 From: de3p666 Date: Sat, 12 Mar 2022 12:06:06 +0100 Subject: [PATCH] version 1.0 --- TODO | 5 + classes/__init__.py | 0 classes/constraints.py | 8 ++ frontend/static/colors.css | 4 + frontend/static/icon.css | 1 + frontend/static/wownero.png | Bin 0 -> 12186 bytes frontend/templates/about/api/index.html | 108 ++++++++++++++ frontend/templates/about/index.html | 125 +++++++++++++++++ frontend/templates/dashboard/index.html | 100 +++++++++++++ frontend/templates/errors/index.html | 30 ++++ frontend/templates/root/index.html | 110 +++++++++++++++ frontend/templates/yellwow/index.html | 126 +++++++++++++++++ .../templates/yellwow/single_user/index.html | 132 ++++++++++++++++++ main.py | 45 ++++++ requirements.txt | 30 ++++ routers/__init__.py | 0 routers/api.py | 32 +++++ routers/auth.py | 68 +++++++++ routers/dashboard.py | 63 +++++++++ routers/db.py | 54 +++++++ routers/errors.py | 2 + routers/static.py | 39 ++++++ 22 files changed, 1082 insertions(+) create mode 100644 TODO create mode 100644 classes/__init__.py create mode 100644 classes/constraints.py create mode 100644 frontend/static/colors.css create mode 100644 frontend/static/icon.css create mode 100644 frontend/static/wownero.png create mode 100644 frontend/templates/about/api/index.html create mode 100644 frontend/templates/about/index.html create mode 100644 frontend/templates/dashboard/index.html create mode 100644 frontend/templates/errors/index.html create mode 100644 frontend/templates/root/index.html create mode 100644 frontend/templates/yellwow/index.html create mode 100644 frontend/templates/yellwow/single_user/index.html create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 routers/__init__.py create mode 100644 routers/api.py create mode 100644 routers/auth.py create mode 100644 routers/dashboard.py create mode 100644 routers/db.py create mode 100644 routers/errors.py create mode 100644 routers/static.py diff --git a/TODO b/TODO new file mode 100644 index 0000000..6b924b6 --- /dev/null +++ b/TODO @@ -0,0 +1,5 @@ +remove Constraints.client_secret before publishing and make a backup of it!! + +Register new application new login.wownero.com + client_id = yellwowpages + client url = /authenticate diff --git a/classes/__init__.py b/classes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/classes/constraints.py b/classes/constraints.py new file mode 100644 index 0000000..06be8ee --- /dev/null +++ b/classes/constraints.py @@ -0,0 +1,8 @@ +from starlette.templating import Jinja2Templates + + +class Constraints: + templates = Jinja2Templates(directory='frontend/templates') + client_id = 'yellwowpagestesting11' + client_secret = '8284d868-f5a1-48f4-a287-8bdb18a7d3a1' + uri = 'sqlite:///users.db' diff --git a/frontend/static/colors.css b/frontend/static/colors.css new file mode 100644 index 0000000..8d2537f --- /dev/null +++ b/frontend/static/colors.css @@ -0,0 +1,4 @@ +:root{ + --yellow: #ffcc00; + --purple: #ff2ad4; +} \ No newline at end of file diff --git a/frontend/static/icon.css b/frontend/static/icon.css new file mode 100644 index 0000000..0057b91 --- /dev/null +++ b/frontend/static/icon.css @@ -0,0 +1 @@ +.icon{box-sizing:border-box;display:inline-block;font-size:inherit;font-style:normal;height:1em;position:relative;text-indent:-9999px;vertical-align:middle;width:1em}.icon::after,.icon::before{content:"";display:block;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.icon.icon-2x{font-size:1.6rem}.icon.icon-3x{font-size:2.4rem}.icon.icon-4x{font-size:3.2rem}.accordion .icon,.btn .icon,.menu .icon,.toast .icon{vertical-align:-10%}.btn-lg .icon{vertical-align:-15%}.icon-arrow-down::before,.icon-arrow-left::before,.icon-arrow-right::before,.icon-arrow-up::before,.icon-back::before,.icon-downward::before,.icon-forward::before,.icon-upward::before{border:.1rem solid currentColor;border-bottom:0;border-right:0;height:.65em;width:.65em}.icon-arrow-down::before{transform:translate(-50%,-75%) rotate(225deg)}.icon-arrow-left::before{transform:translate(-25%,-50%) rotate(-45deg)}.icon-arrow-right::before{transform:translate(-75%,-50%) rotate(135deg)}.icon-arrow-up::before{transform:translate(-50%,-25%) rotate(45deg)}.icon-back::after,.icon-forward::after{background:currentColor;height:.1rem;width:.8em}.icon-downward::after,.icon-upward::after{background:currentColor;height:.8em;width:.1rem}.icon-back::after{left:55%}.icon-back::before{transform:translate(-50%,-50%) rotate(-45deg)}.icon-downward::after{top:45%}.icon-downward::before{transform:translate(-50%,-50%) rotate(-135deg)}.icon-forward::after{left:45%}.icon-forward::before{transform:translate(-50%,-50%) rotate(135deg)}.icon-upward::after{top:55%}.icon-upward::before{transform:translate(-50%,-50%) rotate(45deg)}.icon-caret::before{border-left:.3em solid transparent;border-right:.3em solid transparent;border-top:.3em solid currentColor;height:0;transform:translate(-50%,-25%);width:0}.icon-menu::before{background:currentColor;box-shadow:0 -.35em,0 .35em;height:.1rem;width:100%}.icon-apps::before{background:currentColor;box-shadow:-.35em -.35em,-.35em 0,-.35em .35em,0 -.35em,0 .35em,.35em -.35em,.35em 0,.35em .35em;height:3px;width:3px}.icon-resize-horiz::after,.icon-resize-horiz::before,.icon-resize-vert::after,.icon-resize-vert::before{border:.1rem solid currentColor;border-bottom:0;border-right:0;height:.45em;width:.45em}.icon-resize-horiz::before,.icon-resize-vert::before{transform:translate(-50%,-90%) rotate(45deg)}.icon-resize-horiz::after,.icon-resize-vert::after{transform:translate(-50%,-10%) rotate(225deg)}.icon-resize-horiz::before{transform:translate(-90%,-50%) rotate(-45deg)}.icon-resize-horiz::after{transform:translate(-10%,-50%) rotate(135deg)}.icon-more-horiz::before,.icon-more-vert::before{background:currentColor;border-radius:50%;box-shadow:-.4em 0,.4em 0;height:3px;width:3px}.icon-more-vert::before{box-shadow:0 -.4em,0 .4em}.icon-cross::before,.icon-minus::before,.icon-plus::before{background:currentColor;height:.1rem;width:100%}.icon-cross::after,.icon-plus::after{background:currentColor;height:100%;width:.1rem}.icon-cross::before{width:100%}.icon-cross::after{height:100%}.icon-cross::after,.icon-cross::before{transform:translate(-50%,-50%) rotate(45deg)}.icon-check::before{border:.1rem solid currentColor;border-right:0;border-top:0;height:.5em;transform:translate(-50%,-75%) rotate(-45deg);width:.9em}.icon-stop{border:.1rem solid currentColor;border-radius:50%}.icon-stop::before{background:currentColor;height:.1rem;transform:translate(-50%,-50%) rotate(45deg);width:1em}.icon-shutdown{border:.1rem solid currentColor;border-radius:50%;border-top-color:transparent}.icon-shutdown::before{background:currentColor;content:"";height:.5em;top:.1em;width:.1rem}.icon-refresh::before{border:.1rem solid currentColor;border-radius:50%;border-right-color:transparent;height:1em;width:1em}.icon-refresh::after{border:.2em solid currentColor;border-left-color:transparent;border-top-color:transparent;height:0;left:80%;top:20%;width:0}.icon-search::before{border:.1rem solid currentColor;border-radius:50%;height:.75em;left:5%;top:5%;transform:translate(0,0) rotate(45deg);width:.75em}.icon-search::after{background:currentColor;height:.1rem;left:80%;top:80%;transform:translate(-50%,-50%) rotate(45deg);width:.4em}.icon-edit::before{border:.1rem solid currentColor;height:.4em;transform:translate(-40%,-60%) rotate(-45deg);width:.85em}.icon-edit::after{border:.15em solid currentColor;border-right-color:transparent;border-top-color:transparent;height:0;left:5%;top:95%;transform:translate(0,-100%);width:0}.icon-delete::before{border:.1rem solid currentColor;border-bottom-left-radius:.1rem;border-bottom-right-radius:.1rem;border-top:0;height:.75em;top:60%;width:.75em}.icon-delete::after{background:currentColor;box-shadow:-.25em .2em,.25em .2em;height:.1rem;top:.05rem;width:.5em}.icon-share{border:.1rem solid currentColor;border-radius:.1rem;border-right:0;border-top:0}.icon-share::before{border:.1rem solid currentColor;border-left:0;border-top:0;height:.4em;left:100%;top:.25em;transform:translate(-125%,-50%) rotate(-45deg);width:.4em}.icon-share::after{border:.1rem solid currentColor;border-bottom:0;border-radius:75% 0;border-right:0;height:.5em;width:.6em}.icon-flag::before{background:currentColor;height:1em;left:15%;width:.1rem}.icon-flag::after{border:.1rem solid currentColor;border-bottom-right-radius:.1rem;border-left:0;border-top-right-radius:.1rem;height:.65em;left:60%;top:35%;width:.8em}.icon-bookmark::before{border:.1rem solid currentColor;border-bottom:0;border-top-left-radius:.1rem;border-top-right-radius:.1rem;height:.9em;width:.8em}.icon-bookmark::after{border:.1rem solid currentColor;border-bottom:0;border-left:0;border-radius:.1rem;height:.5em;transform:translate(-50%,35%) rotate(-45deg) skew(15deg,15deg);width:.5em}.icon-download,.icon-upload{border-bottom:.1rem solid currentColor}.icon-download::before,.icon-upload::before{border:.1rem solid currentColor;border-bottom:0;border-right:0;height:.5em;transform:translate(-50%,-60%) rotate(-135deg);width:.5em}.icon-download::after,.icon-upload::after{background:currentColor;height:.6em;top:40%;width:.1rem}.icon-upload::before{transform:translate(-50%,-60%) rotate(45deg)}.icon-upload::after{top:50%}.icon-copy::before{border:.1rem solid currentColor;border-bottom:0;border-radius:.1rem;border-right:0;height:.8em;left:40%;top:35%;width:.8em}.icon-copy::after{border:.1rem solid currentColor;border-radius:.1rem;height:.8em;left:60%;top:60%;width:.8em}.icon-time{border:.1rem solid currentColor;border-radius:50%}.icon-time::before{background:currentColor;height:.4em;transform:translate(-50%,-75%);width:.1rem}.icon-time::after{background:currentColor;height:.3em;transform:translate(-50%,-75%) rotate(90deg);transform-origin:50% 90%;width:.1rem}.icon-mail::before{border:.1rem solid currentColor;border-radius:.1rem;height:.8em;width:1em}.icon-mail::after{border:.1rem solid currentColor;border-right:0;border-top:0;height:.5em;transform:translate(-50%,-90%) rotate(-45deg) skew(10deg,10deg);width:.5em}.icon-people::before{border:.1rem solid currentColor;border-radius:50%;height:.45em;top:25%;width:.45em}.icon-people::after{border:.1rem solid currentColor;border-radius:50% 50% 0 0;height:.4em;top:75%;width:.9em}.icon-message{border:.1rem solid currentColor;border-bottom:0;border-radius:.1rem;border-right:0}.icon-message::before{border:.1rem solid currentColor;border-bottom-right-radius:.1rem;border-left:0;border-top:0;height:.8em;left:65%;top:40%;width:.7em}.icon-message::after{background:currentColor;border-radius:.1rem;height:.3em;left:10%;top:100%;transform:translate(0,-90%) rotate(45deg);width:.1rem}.icon-photo{border:.1rem solid currentColor;border-radius:.1rem}.icon-photo::before{border:.1rem solid currentColor;border-radius:50%;height:.25em;left:35%;top:35%;width:.25em}.icon-photo::after{border:.1rem solid currentColor;border-bottom:0;border-left:0;height:.5em;left:60%;transform:translate(-50%,25%) rotate(-45deg);width:.5em}.icon-link::after,.icon-link::before{border:.1rem solid currentColor;border-radius:5em 0 0 5em;border-right:0;height:.5em;width:.75em}.icon-link::before{transform:translate(-70%,-45%) rotate(-45deg)}.icon-link::after{transform:translate(-30%,-55%) rotate(135deg)}.icon-location::before{border:.1rem solid currentColor;border-radius:50% 50% 50% 0;height:.8em;transform:translate(-50%,-60%) rotate(-45deg);width:.8em}.icon-location::after{border:.1rem solid currentColor;border-radius:50%;height:.2em;transform:translate(-50%,-80%);width:.2em}.icon-emoji{border:.1rem solid currentColor;border-radius:50%}.icon-emoji::before{border-radius:50%;box-shadow:-.17em -.1em,.17em -.1em;height:.15em;width:.15em}.icon-emoji::after{border:.1rem solid currentColor;border-bottom-color:transparent;border-radius:50%;border-right-color:transparent;height:.5em;transform:translate(-50%,-40%) rotate(-135deg);width:.5em} \ No newline at end of file diff --git a/frontend/static/wownero.png b/frontend/static/wownero.png new file mode 100644 index 0000000000000000000000000000000000000000..02a262bfb54fd169c1fa7ff9493cb6f7698af743 GIT binary patch literal 12186 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 + + + + + + YellWOWPages - Sex and Drugs in the metaverse + + + + + + +
+ +
+
+
+

About - Api

+

+ Search user: /api/user/{username} +

+ Get all users: /api/all +

+
+
+ + + \ No newline at end of file diff --git a/frontend/templates/about/index.html b/frontend/templates/about/index.html new file mode 100644 index 0000000..d1a4cf1 --- /dev/null +++ b/frontend/templates/about/index.html @@ -0,0 +1,125 @@ + + + + + + + YellWOWPages - Sex and Drugs in the metaverse + + + + + + +
+ +
+
+
+

About

+

+ Search for any Wownero sub-address you want by username and pay + the world! +
+ This application uses Wownero's Centralized Authentication Service. +

+

+ Other Wownero related stuff: +
+ WebSite +
+ SuchWow +
+ Official Git +
+ Discord server +

+

+ Idea of: dsc_ +
+ Made by NotMtth +

+
+
+ + + \ No newline at end of file diff --git a/frontend/templates/dashboard/index.html b/frontend/templates/dashboard/index.html new file mode 100644 index 0000000..bfada88 --- /dev/null +++ b/frontend/templates/dashboard/index.html @@ -0,0 +1,100 @@ + + + + + + + Such dashboard + + + + + + +
+ +
+
+
+
+ {% for username, address in user_data.items() %} +
Welcome back {{username}}!
+ Current sub-address: +
+ Change sub-address: +
+ + +
+
+ {% endfor %} +
+
+
+ + + \ No newline at end of file diff --git a/frontend/templates/errors/index.html b/frontend/templates/errors/index.html new file mode 100644 index 0000000..f5b817d --- /dev/null +++ b/frontend/templates/errors/index.html @@ -0,0 +1,30 @@ + + + + + + + + Such error :( + + + + + + +
+
+

Error: {{error}}

+
+
+ + \ No newline at end of file diff --git a/frontend/templates/root/index.html b/frontend/templates/root/index.html new file mode 100644 index 0000000..52bfe40 --- /dev/null +++ b/frontend/templates/root/index.html @@ -0,0 +1,110 @@ + + + + + + + YellWOWPages - Sex and Drugs in the metaverse + + + + + + +
+ +
+
+
+
+ YellWOWPages +
+
+ The first addresses library - + from the community to the community +
+
+
+ + + \ No newline at end of file diff --git a/frontend/templates/yellwow/index.html b/frontend/templates/yellwow/index.html new file mode 100644 index 0000000..a937f51 --- /dev/null +++ b/frontend/templates/yellwow/index.html @@ -0,0 +1,126 @@ + + + + + + + YellWOWPages - Sex and Drugs in the metaverse + + + + + + +
+ +
+
+
+
+ + +
+
+ {% for username, address in user_data.items() %} +
+
+ {{username}} +
+ {{address}} +
+ {% endfor %} +
+
+
+ + + \ No newline at end of file diff --git a/frontend/templates/yellwow/single_user/index.html b/frontend/templates/yellwow/single_user/index.html new file mode 100644 index 0000000..9c32b8a --- /dev/null +++ b/frontend/templates/yellwow/single_user/index.html @@ -0,0 +1,132 @@ + + + + + + + YellWOWPages - Sex and Drugs in the metaverse + + + + + + +
+ +
+
+
+
+ + +
+
+ Result: {{user_data|length}} + {% if not user_data|length %} + Nothing found... + {% else %} +
+ {% for username, address in user_data.items() %} +
+
+ {{username}} +
+ {{address}} +
+ {% endfor %} +
+ {% endif %} +
+
+ + + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..4344355 --- /dev/null +++ b/main.py @@ -0,0 +1,45 @@ +from fastapi import FastAPI, Request +from fastapi.responses import HTMLResponse +from fastapi.staticfiles import StaticFiles +import uvicorn + +from classes.constraints import Constraints + +from starlette.exceptions import HTTPException as StarletteHTTPException + +app = FastAPI(docs_url=None, redoc_url=None) + +app.mount('/static', StaticFiles(directory='frontend/static'), name='static') + +from routers import auth, static, dashboard, db, api + +app.include_router(auth.router) +app.include_router(dashboard.router) +app.include_router(static.router) +app.include_router(api.router) + + +@app.get("/") +@app.get('/root', response_class=HTMLResponse) +async def root(request: Request): + return Constraints.templates.TemplateResponse('/root/index.html', {'request': request}) + + +# shitty error handling +@app.exception_handler(StarletteHTTPException) +async def http_exception_handler(request, exc): + if exc.status_code == 404: + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': 'not found...', + 'url': '/root'}) + elif exc.status_code == 500: + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': 'internal server error', + 'url': '/root'}) + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': exc.detail, + 'url': '/root'}) + + +if __name__ == '__main__': + uvicorn.run(app, host='127.0.0.1', port=8080) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b9939be --- /dev/null +++ b/requirements.txt @@ -0,0 +1,30 @@ +anyio==3.5.0 +asgiref==3.5.0 +asttokens==2.0.5 +certifi==2021.10.8 +charset-normalizer==2.0.12 +click==8.0.4 +colorama==0.4.4 +executing==0.8.3 +fastapi==0.75.0 +Flask==2.0.3 +Flask-SQLAlchemy==2.5.1 +greenlet==1.1.2 +h11==0.13.0 +icecream==2.1.2 +idna==3.3 +itsdangerous==2.1.1 +Jinja2==3.0.3 +MarkupSafe==2.1.0 +pydantic==1.9.0 +Pygments==2.11.2 +python-multipart==0.0.5 +requests==2.27.1 +six==1.16.0 +sniffio==1.2.0 +SQLAlchemy==1.4.32 +starlette==0.17.1 +typing-extensions==4.1.1 +urllib3==1.26.8 +uvicorn==0.17.5 +Werkzeug==2.0.3 diff --git a/routers/__init__.py b/routers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/routers/api.py b/routers/api.py new file mode 100644 index 0000000..cc8c8bc --- /dev/null +++ b/routers/api.py @@ -0,0 +1,32 @@ +from fastapi import APIRouter, Request, Form +from fastapi.responses import RedirectResponse, HTMLResponse +from icecream import ic + +from classes.constraints import Constraints +from .db import Database + +router = APIRouter() + + +# external api +@router.get('/api/user/{username}') +async def get_api(request: Request, username: str): + if not Database.Users.get_address(username): + return {'error': 'invalid user'} + return Database.Users.get_address(username) + + +@router.get('/api/all') +async def get_api_all(request: Request): + return Database.Users.get_all() + + +# site search redirect +@router.get('/search') +async def search_api(request: Request): + username = request.query_params['username'] + ic(request.query_params.get('switch', None) == 'on') + if request.query_params.get('switch', None) == 'on': + return RedirectResponse(f'/yellwowpage/matches/{username}') + else: + return RedirectResponse(f'/yellwowpage/user/{username}') diff --git a/routers/auth.py b/routers/auth.py new file mode 100644 index 0000000..c9e2155 --- /dev/null +++ b/routers/auth.py @@ -0,0 +1,68 @@ +from fastapi import APIRouter, Request, Cookie +from fastapi.responses import RedirectResponse, HTMLResponse +import requests +from icecream import ic +import secrets + +from classes.constraints import Constraints + +router = APIRouter() + + +@router.get('/login') +async def get_login(request: Request): + state = secrets.token_hex(10) + response = RedirectResponse( + 'https://login.wownero.com/auth/realms/master/protocol/openid-connect/auth?'f'client_id=' + f'{Constraints.client_id}&redirect_uri=http://127.0.0.1:8080/authenticate&' + f'response_type=code&state={state}') + response.set_cookie(key='state', value=state) + return response + + +@router.get('/authenticate') +async def get_auth(request: Request, state: str = Cookie(None)): + params = request.query_params + if state is None: + return Constraints.templates.TemplateResponse('/errors/index.html', + {'request': request, + 'error': '`state` security code not found...', + 'url': '/login'}) + if params['state'] != state: + return Constraints.templates.TemplateResponse('/errors/index.html', + {'request': request, + 'error': '`state` security code is wrong', + 'url': '/login'}) + url = "https://login.wownero.com/auth/realms/master/protocol/openid-connect/token" + data = { + "grant_type": "authorization_code", + "code": params["code"], + "redirect_uri": "http://127.0.0.1:8080/authenticate", + "client_id": f'{Constraints.client_id}', + "client_secret": f'{Constraints.client_secret}', + "state": params['state'] + } + r = requests.post(url=url, data=data) + response = r.json() + + if response.get('error', None) is not None: + return Constraints.templates.TemplateResponse('/errors/index.html', + {'request': request, 'error': r.json()['error_description'], + 'url': '/login'}) + auth_code = response.get('access_token', None) + + if auth_code is None: + return Constraints.templates.TemplateResponse('/errors/index.html', + {'request': request, 'error': 'invalid auth code', + 'url': '/login'}) + response = RedirectResponse('/dashboard') + response.set_cookie(key='auth_code', value=auth_code) + response.delete_cookie(key='state') + return response + + +@router.get('/logout') +async def get_logout(): + response = RedirectResponse('/root') + response.delete_cookie('auth_code') + return response diff --git a/routers/dashboard.py b/routers/dashboard.py new file mode 100644 index 0000000..c2e13c5 --- /dev/null +++ b/routers/dashboard.py @@ -0,0 +1,63 @@ +from fastapi import APIRouter, Request, Cookie, Form +from fastapi.responses import RedirectResponse, HTMLResponse +import requests +from icecream import ic + +from classes.constraints import Constraints +from .db import Database + +router = APIRouter() + + +@router.get('/dashboard', response_class=HTMLResponse) +async def get_dashboard(request: Request, auth_code: str = Cookie(None)): + if auth_code is None: + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': 'not logged in', + 'url': '/login'}) + + url = "https://login.wownero.com/auth/realms/master/protocol/openid-connect/userinfo" + response = requests.post(url, headers={"Authorization": f"Bearer {auth_code}"}) + user_profile = response.json() + + if user_profile.get('preferred_username', None) is None: + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': 'account not found...', + 'url': '/login'}) + user_name = user_profile.get('preferred_username', None) + return Constraints.templates.TemplateResponse('/dashboard/index.html', {'request': request, + 'user_data': Database.Users.get_address(user_name)}) + + +@router.post('/submit_address') +async def post_submit_address(request: Request, auth_code: str = Cookie(None), address: str = Form(None)): + if auth_code is None: + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': 'not logged in', + 'url': '/login'}) + if address is None: + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': 'invalid address', + 'url': '/dashboard'}) + + if len(address) != 97: + return Constraints.templates.TemplateResponse('/errors/index.html', {'request': request, + 'error': 'invalid address length', + 'url': '/dashboard'}) + + url = "https://login.wownero.com/auth/realms/master/protocol/openid-connect/userinfo" + response = requests.post(url, headers={"Authorization": f"Bearer {auth_code}"}) + user_name = response.json().get('preferred_username', None) + + if not Database.Users.get_address(user_name): + new_user = Database.Users(username=user_name, address=address) + Database.sqla.session.add(new_user) + Database.sqla.session.commit() + return RedirectResponse('/dashboard', status_code=303) + + update_address = Database.Users.query.filter_by(username=user_name).first() + update_address.address = address + Database.sqla.session.commit() + return RedirectResponse('/dashboard', status_code=303) + + diff --git a/routers/db.py b/routers/db.py new file mode 100644 index 0000000..d938900 --- /dev/null +++ b/routers/db.py @@ -0,0 +1,54 @@ +from flask import Flask +from flask_sqlalchemy import SQLAlchemy + +from icecream import install, ic + +from classes.constraints import Constraints + +app = Flask(__name__) +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +app.config['SQLALCHEMY_DATABASE_URI'] = Constraints.uri +db = SQLAlchemy(app, session_options={'autocommit': False}) + + +class Users(db.Model): + __tablename__ = 'wowusers' + username = db.Column(db.VARCHAR(32), primary_key=True) + address = db.Column(db.CHAR(97), nullable=False) + + @staticmethod + def get_address(username): + user_data = {} + try: + user_data.update({Users.query.filter_by(username=username).first().username: + Users.query.filter_by(username=username).first().address}) + except AttributeError: + return user_data + return user_data + + @staticmethod + def get_all(): + users_data = {} + for user in Users.query.all(): + users_data.update({user.username: user.address}) + return users_data + + @staticmethod + def get_matches(username): + user_data = {} + try: + for i in range(3): + user = Users.query.filter(Database.Users.username.like(f'%{username}%'))[i] + user_data.update({user.username: user.address}) + except IndexError: + return user_data + return user_data + + +class Database: + Users = Users + sqla = db + + +db.create_all() +ic('db done') diff --git a/routers/errors.py b/routers/errors.py new file mode 100644 index 0000000..86c3b6c --- /dev/null +++ b/routers/errors.py @@ -0,0 +1,2 @@ +# stupid fastapi error handling drove me crazy for some hours, updating this asap +# the handler is in the main file diff --git a/routers/static.py b/routers/static.py new file mode 100644 index 0000000..232e23d --- /dev/null +++ b/routers/static.py @@ -0,0 +1,39 @@ +from fastapi import APIRouter, Request +from fastapi.responses import RedirectResponse, HTMLResponse +from icecream import ic + +from classes.constraints import Constraints +from .db import Database + +router = APIRouter() + + +@router.get('/yellwowpage') +async def get_yellwowpage(request: Request): + return Constraints.templates.TemplateResponse('/yellwow/index.html', + {'request': request, 'user_data': Database.Users.get_all()}) + + +@router.get('/yellwowpage/user/{username}') +async def get_yellwowpage(request: Request, username: str): + return Constraints.templates.TemplateResponse('/yellwow/single_user/index.html', + {'request': request, + 'user_data': Database.Users.get_address(username)}) + + +@router.get('/yellwowpage/matches/{username}') +async def get_yellwowpage_matches(request: Request, username: str): + ic(Database.Users.get_matches(username)) + return Constraints.templates.TemplateResponse('/yellwow/single_user/index.html', + {'request': request, + 'user_data': Database.Users.get_matches(username)}) + + +@router.get('/about') +async def get_about(request: Request): + return Constraints.templates.TemplateResponse('/about/index.html', {'request': request}) + + +@router.get('/about/api') +async def get_api_about(request: Request): + return Constraints.templates.TemplateResponse('/about/api/index.html', {'request': request})