Flask login with Telegram

This commit is contained in:
Johnny Gear 2026-01-09 16:56:54 -06:00
parent b18c6ae6e8
commit 849754ea4a
6 changed files with 136 additions and 0 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
.env
*~
db.sqlite3
Caddyfile

View file

@ -10,6 +10,8 @@ scheduler = "*"
pytz = "*"
peewee = "*"
peewee-migrate = "*"
flask = "*"
flask-login = "*"
[dev-packages]

62
flask/app.py Normal file
View file

@ -0,0 +1,62 @@
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from flask import Flask, render_template, request, jsonify, redirect
from flask_login import LoginManager, UserMixin
import hashlib
import hmac
import base64
from settings import FLASK_SECRET_KEY, TELEGRAM_API_TOKEN, TELEGRAM_BOT_NAME, TELEGRAM_BOT_DOMAIN
app = Flask(__name__)
app.secret_key = FLASK_SECRET_KEY
@app.route('/')
def index():
data = {'bot_name': TELEGRAM_BOT_NAME, 'bot_damin': TELEGRAM_BOT_DOMAIN}
return render_template('index.html', data = data)
@app.route('/dashboard')
def dashboard():
return render_template('dashboard.html')
def string_generator(data_incoming):
data = data_incoming.copy()
del data['hash']
keys = sorted(data.keys())
string_arr = []
for key in keys:
string_arr.append(key + '=' + data[key])
string_cat = '\n'.join(string_arr)
return string_cat
@app.route('/login')
def login():
tg_data = {
"id": request.args.get("id", None),
"first_name": request.args.get('first_name', None),
"last_name": request.args.get('last_name', None),
"username": request.args.get("username", None),
"photo_url": request.args.get("photo_url", None),
"auth_date": request.args.get('auth_date', None),
"hash": request.args.get("hash", None)
}
data_check_string = string_generator(tg_data)
secret_key = hashlib.sha256(TELEGRAM_API_TOKEN.encode('utf-8')).digest()
secret_key_bytes = secret_key
data_check_string_bytes = bytes(data_check_string, 'utf-8')
hmac_string = hmac.new(secret_key_bytes, data_check_string_bytes, hashlib.sha256).hexdigest()
if hmac_string == tg_data['hash']:
return redirect('/dashboard')
return jsonify({
'hmac_string': hmac_string,
'tg_hash': tg_data['hash'],
'tg_data': tg_data
})
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=8080)

View file

@ -0,0 +1,34 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<title>Dashboard</title>
</head>
<body class="w-100 h-100">
<div id="s_cover3" class="pt-5 pi-draggable text-white bg-primary">
<div class="container">
<div class="row">
<div class="col-md-12 text-md-left text-center align-self-center my-5">
<h1 class="display-1">Dashboard</h1>
<p class="lead">Successfuly logged in and the login verified</p>
</div>
</div>
</div>
</div>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css">
<link rel="stylesheet" href="theme.css" type="text/css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>

View file

@ -0,0 +1,33 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<div class="py-5 text-center opaque-overlay filter-gradient">
<div class="container py-5">
<div class="row">
<div class="col-md-12 text-white">
<h1 class="display-3 mb-4">Telegram Login</h1>
<p class="lead mb-5">A simple telegram login using flask. The instructions can be found
<br>mithun.co</p>
<script async src="https://telegram.org/js/telegram-widget.js?19" data-telegram-login="{{ data['bot_name'] }}" data-size="large" data-auth-url="{{ data['bot_domain'] }}/login" data-request-access="write"></script>
</div>
</div>
</div>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>

View file

@ -16,6 +16,8 @@ MASTODON_VISIBILITY = os.environ.get('MASTODON_VISIBILITY', 'direct')
TELEGRAM_API_TOKEN = os.environ.get('TELEGRAM_API_TOKEN')
TELEGRAM_CHAT_ID = int(os.environ.get('TELEGRAM_CHAT_ID'))
TELEGRAM_COMMAND_TIMEOUT = int(os.environ.get('TELEGRAM_COMMAND_TIMEOUT', 120))
TELEGRAM_BOT_NAME = os.environ.get('TELEGRAM_BOT_NAME')
TELEGRAM_BOT_DOMAIN = os.environ.get('TELEGRAM_BOT_DOMAIN')
SQLITE_DB = os.environ.get('SQLITE_DB', 'db.sqlite3')
@ -24,3 +26,4 @@ ORDERS_YML = os.environ.get('ORDERS_YML', 'orders.yml')
TIMEZONE = os.environ.get('TIMEZONE', 'America/Chicago')
FLASK_URL = os.environ.get("FLASK_URL")
FLASK_SECRET_KEY = os.environ.get("FLASK_SECRET_KEY")