From 1414be5fc8d28bc0feda31d9033f52fb53f26437 Mon Sep 17 00:00:00 2001 From: Nathan Woodburn Date: Wed, 19 Jun 2024 14:07:05 +1000 Subject: [PATCH] feat: Add plain auth method --- website/models.py | 16 ++++++++++++- website/routes.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/website/models.py b/website/models.py index 06a2ea9..29e1f6f 100644 --- a/website/models.py +++ b/website/models.py @@ -57,4 +57,18 @@ class OAuth2Token(db.Model, OAuth2TokenMixin): if self.revoked: return False expires_at = self.issued_at + self.expires_in * 2 - return expires_at >= time.time() \ No newline at end of file + return expires_at >= time.time() + + +class AuthTokens(db.Model): + id = db.Column(db.Integer, primary_key=True) + service = db.Column(db.String(255)) + user_name = db.Column(db.String(255)) + access_token = db.Column(db.String(255)) + refresh_token = db.Column(db.String(255)) + expires_at = db.Column(db.Integer) + + def is_refresh_token_active(self): + if self.revoked: + return False + return self.expires_at >= time.time() \ No newline at end of file diff --git a/website/routes.py b/website/routes.py index 6c93c2b..3d2ffaf 100644 --- a/website/routes.py +++ b/website/routes.py @@ -1,11 +1,12 @@ import time +import datetime as dt from .varo_auth import flask_login as varo_auth_flask_login from flask import Blueprint, request, session, url_for, make_response from flask import render_template, redirect, jsonify, send_from_directory from werkzeug.security import gen_salt from authlib.integrations.flask_oauth2 import current_token from authlib.oauth2 import OAuth2Error -from .models import db, User, OAuth2Client +from .models import db, User, OAuth2Client, AuthTokens from .oauth2 import authorization, require_oauth import os import requests @@ -453,6 +454,61 @@ def authorize(): return authorization.create_authorization_response(grant_user=grant_user) +@bp.route("/auth", methods=["GET", "POST"]) +def plainAuth(): + user:User = current_user() + if not user: + return redirect(url_for("home.home", next=request.url)) + + # Check for return URL + return_url = request.args.get("return") + if not return_url: + return render_template("error.html",error="No return URL specified") + + # Get host from return URL + host = return_url.split("/")[2] + + + if request.method == "GET": + # Custom grant + grant = { + "client":{ + "client_name": host, + } + } + return render_template("authorize.html", user=user, grant=grant) + + # Create a hex token for the user + token = gen_salt(24) + + expiry = dt.datetime.now() + timedelta(days=7) + # Save the token in the database + auth_token = AuthTokens(service=host, user_name=user.username, access_token=token, refresh_token="", expires_at=expiry) + db.session.add(auth_token) + db.session.commit() + + # Remove any stale tokens + AuthTokens.query.filter(AuthTokens.expires_at < time.time()).delete() + + + return redirect(return_url+"?username="+user.username+"&token="+token) + +@bp.route("/auth/user") +def authUser(): + if "token" not in request.args: + return jsonify({"error": "No token specified"}) + + token = request.args.get("token") + # Remove any stale tokens + AuthTokens.query.filter(AuthTokens.expires_at < time.time()).delete() + + username = AuthTokens.query.filter_by(access_token=token).first() + if not username: + return jsonify({"error": "Invalid token"}) + + user = User.query.filter_by(username=username.user_name).first() + + return jsonify(get_user_info(user)) @bp.route("/oauth/token", methods=["POST"]) def issue_token():