~fnux/meta.sr.ht

6d8a5e25f0796b31d41502620f2078eb14731ccc — Drew DeVault 8 months ago c1eeb3a
all: style
M metasrht/app.py => metasrht/app.py +3 -4
@@ 1,11 1,10 @@
from flask import session
from srht.config import cfg
from srht.database import DbSession
from srht.flask import SrhtFlask

from metasrht.auth import allow_registration, is_external_auth
from metasrht.oauth import MetaOAuthService, MetaOAuthProvider
from metasrht.types import UserType
from srht.config import cfg
from srht.database import DbSession
from srht.flask import SrhtFlask

db = DbSession(cfg("meta.sr.ht", "connection-string"))
db.init()

M metasrht/audit.py => metasrht/audit.py +3 -3
@@ 1,11 1,11 @@
from datetime import datetime, timedelta
from flask import request
from ipaddress import ip_address
from datetime import datetime, timedelta
from metasrht.email import send_email
from metasrht.types import AuditLogEntry
from srht.config import cfg
from srht.database import db
from srht.oauth import current_user
from metasrht.email import send_email
from metasrht.types import AuditLogEntry

def audit_log(event_type, details=None, user=None,
        email=False, subject=None, email_details=None):

M metasrht/auth_validation.py => metasrht/auth_validation.py +3 -6
@@ 1,11 1,9 @@
import re

from jinja2 import Markup
from srht.config import cfg
from zxcvbn import zxcvbn

from metasrht.blacklist import email_blacklist, username_blacklist
from metasrht.types import User
from srht.config import cfg
from zxcvbn import zxcvbn


def validate_username(valid, username):


@@ 47,8 45,7 @@ def validate_password(valid, password):
    if cfg("sr.ht", "environment", default="production") == "development":
        return
    strength = zxcvbn(password)
    time = \
        strength["crack_times_display"]["offline_slow_hashing_1e4_per_second"]
    time = strength["crack_times_display"]["offline_slow_hashing_1e4_per_second"]
    valid.expect(strength["score"] >= 3, Markup(
        "This password is too weak — it could be cracked in " +
        f"{time} if our database were broken into. Try using " +

M metasrht/billing.py => metasrht/billing.py +3 -3
@@ 1,10 1,10 @@
import stripe
from datetime import datetime, timedelta
from srht.config import cfg
from srht.database import db
from enum import Enum
from metasrht.audit import audit_log
from metasrht.types import User, UserType, PaymentInterval, Invoice
from enum import Enum
from srht.config import cfg
from srht.database import db

stripe.api_key = cfg("meta.sr.ht::billing", "stripe-secret-key")


M metasrht/blueprints/auth.py => metasrht/blueprints/auth.py +13 -15
@@ 1,26 1,24 @@
from datetime import datetime
from urllib.parse import urlparse

from flask import Blueprint, render_template, abort, request, redirect
from flask import url_for
from prometheus_client import Counter
from srht.config import cfg, get_global_domain
from srht.database import db
from srht.flask import csrf_bypass, session
from srht.oauth import current_user, login_user, logout_user
from srht.validation import Validation

from metasrht.audit import audit_log
from metasrht.auth import allow_registration, user_valid, prepare_user, \
    is_external_auth
from metasrht.auth import allow_registration, user_valid, prepare_user
from metasrht.auth import is_external_auth
from metasrht.auth.builtin import hash_password, check_password
from metasrht.auth_validation import validate_username, validate_email, \
    validate_password
from metasrht.auth_validation import validate_password
from metasrht.auth_validation import validate_username, validate_email
from metasrht.email import send_email
from metasrht.totp import totp
from metasrht.types import User, UserType, Invite
from metasrht.types import UserAuthFactor, FactorType, PGPKey
from metasrht.webhooks import UserWebhook
from prometheus_client import Counter
from srht.config import cfg, get_global_domain
from srht.database import db
from srht.flask import csrf_bypass, session
from srht.oauth import current_user, login_user, logout_user
from srht.validation import Validation
from urllib.parse import urlparse

auth = Blueprint('auth', __name__)



@@ 268,8 266,8 @@ def login_POST():

    user = prepare_user(username)

    factors = UserAuthFactor.query \
        .filter(UserAuthFactor.user_id == user.id).all()
    factors = (UserAuthFactor.query
        .filter(UserAuthFactor.user_id == user.id)).all()

    if any(factors):
        session['extra_factors'] = [f.id for f in factors]

M metasrht/blueprints/billing.py => metasrht/blueprints/billing.py +5 -5
@@ 3,16 3,16 @@ from datetime import datetime, timedelta
from flask import Blueprint, render_template, request, redirect
from flask import url_for, abort, Response
from jinja2 import escape
from metasrht.audit import audit_log
from metasrht.billing import charge_user
from metasrht.types import User, UserType, PaymentInterval, Invoice
from metasrht.webhooks import deliver_profile_update
from sqlalchemy import and_
from srht.database import db
from srht.config import cfg
from srht.database import db
from srht.flask import session
from srht.oauth import current_user, loginrequired, freshen_user
from srht.validation import Validation
from metasrht.audit import audit_log
from metasrht.billing import charge_user
from metasrht.types import User, UserType, PaymentInterval, Invoice
from metasrht.webhooks import deliver_profile_update
from weasyprint import HTML, CSS

billing = Blueprint('billing', __name__)

M metasrht/blueprints/invites.py => metasrht/blueprints/invites.py +1 -1
@@ 1,9 1,9 @@
from flask import Blueprint, render_template, redirect, abort
from metasrht.types import Invite, UserType
from srht.config import cfg
from srht.database import db
from srht.flask import session
from srht.oauth import current_user, loginrequired
from metasrht.types import Invite, UserType

invites = Blueprint('invites', __name__)


M metasrht/blueprints/oauth_exchange.py => metasrht/blueprints/oauth_exchange.py +7 -7
@@ 1,17 1,17 @@
from flask import Blueprint, render_template, request, redirect
import hashlib
import json
import os
import urllib
from datetime import datetime, timedelta
from metasrht.types import OAuthClient, OAuthToken, User, RevocationUrl
from flask import Blueprint, render_template, request, redirect
from metasrht.audit import audit_log
from metasrht.oauth import OAuthScope
from metasrht.types import OAuthClient, OAuthToken, User, RevocationUrl
from srht.database import db
from srht.flask import csrf_bypass
from srht.oauth import current_user, loginrequired
from srht.redis import redis
from srht.validation import Validation
import os
import json
import hashlib
import urllib

oauth_exchange = Blueprint('oauth_exchange', __name__)



@@ 79,7 79,7 @@ def oauth_authorize_GET():
                error='invalid_scope', details=ex.args[0])

    if redirect_uri != "urn:ietf:wg:oauth:2.0:oob":
        previous = (OAuthToken.query\
        previous = (OAuthToken.query
            .filter(OAuthToken.user_id == current_user.id)
            .filter(OAuthToken.client_id == client.id)
            .filter(OAuthToken.expires > datetime.utcnow())

M metasrht/blueprints/oauth_web.py => metasrht/blueprints/oauth_web.py +3 -3
@@ 1,14 1,14 @@
import json
from flask import Blueprint, render_template, request, redirect, abort
from datetime import datetime
from flask import Blueprint, render_template, request, redirect, abort
from metasrht.audit import audit_log
from metasrht.types import OAuthClient, OAuthToken, DelegatedScope
from metasrht.types import RevocationUrl
from metasrht.audit import audit_log
from srht.database import db
from srht.flask import session
from srht.oauth import current_user, loginrequired
from srht.webhook.celery import async_request
from srht.validation import Validation, valid_url
from srht.webhook.celery import async_request

oauth_web = Blueprint('oauth_web', __name__)


M metasrht/blueprints/privacy.py => metasrht/blueprints/privacy.py +1 -1
@@ 1,7 1,7 @@
from flask import Blueprint, Response, render_template, request, redirect
from metasrht.audit import audit_log
from metasrht.types import User, PGPKey
from metasrht.email import send_email
from metasrht.types import User, PGPKey
from srht.config import cfg
from srht.database import db
from srht.oauth import current_user, loginrequired

M metasrht/blueprints/security.py => metasrht/blueprints/security.py +12 -15
@@ 28,14 28,12 @@ metrics = type("metrics", tuple(), {
@security.route("/security")
@loginrequired
def security_GET():
    totp = UserAuthFactor.query \
        .filter(UserAuthFactor.user_id == current_user.id) \
        .filter(UserAuthFactor.factor_type == FactorType.totp) \
        .one_or_none()
    audit_log = AuditLogEntry.query \
        .filter(AuditLogEntry.user_id == current_user.id) \
        .order_by(AuditLogEntry.created.desc()) \
        .limit(15)
    totp = (UserAuthFactor.query
        .filter(UserAuthFactor.user_id == current_user.id)
        .filter(UserAuthFactor.factor_type == FactorType.totp)).one_or_none()
    audit_log = (AuditLogEntry.query
        .filter(AuditLogEntry.user_id == current_user.id)
        .order_by(AuditLogEntry.created.desc())).limit(15)
    return render_template("security.html",
        audit_log=audit_log,
        totp=totp)


@@ 43,9 41,9 @@ def security_GET():
@security.route("/security/audit/log")
@loginrequired
def security_audit_log_GET():
    audit_log = AuditLogEntry.query \
        .filter(AuditLogEntry.user_id == current_user.id) \
        .order_by(AuditLogEntry.created.desc()).all()
    audit_log = (AuditLogEntry.query
        .filter(AuditLogEntry.user_id == current_user.id)
        .order_by(AuditLogEntry.created.desc())).all()
    return render_template("audit-log.html", audit_log=audit_log)

def totp_get_qrcode(secret):


@@ 132,10 130,9 @@ def security_totp_complete():
@security.route("/security/totp/disable", methods=["POST"])
@loginrequired
def security_totp_disable_POST():
    factor = UserAuthFactor.query \
            .filter(UserAuthFactor.user_id == current_user.id)\
            .filter(UserAuthFactor.factor_type == FactorType.totp)\
            .one_or_none()
    factor = (UserAuthFactor.query
        .filter(UserAuthFactor.user_id == current_user.id)
        .filter(UserAuthFactor.factor_type == FactorType.totp)).one_or_none()
    if not factor:
        return redirect("/security")
    db.session.delete(factor)

M metasrht/blueprints/users.py => metasrht/blueprints/users.py +5 -7
@@ 1,6 1,10 @@
from datetime import datetime, timedelta

from flask import Blueprint, render_template, request, redirect, url_for, abort
from metasrht.decorators import adminrequired
from metasrht.types import Invoice
from metasrht.types import User, UserAuthFactor, FactorType, AuditLogEntry
from metasrht.types import UserNote, PaymentInterval
from metasrht.webhooks import UserWebhook
from sqlalchemy import and_
from srht.database import db
from srht.flask import paginate_query


@@ 8,12 12,6 @@ from srht.oauth import UserType
from srht.search import search_by
from srht.validation import Validation

from metasrht.decorators import adminrequired
from metasrht.types import User, UserAuthFactor, FactorType, AuditLogEntry, \
    Invoice
from metasrht.types import UserNote, PaymentInterval
from metasrht.webhooks import UserWebhook

users = Blueprint("users", __name__)

@users.route("/users")

M metasrht/email.py => metasrht/email.py +3 -3
@@ 1,7 1,7 @@
import os
import srht.email
import html.parser
import os
import pystache
import srht.email
from srht.config import cfg, cfgi
from srht.oauth import current_user



@@ 12,7 12,7 @@ site_name = cfg("sr.ht", "site-name")

def send_email(template, *args, encrypt_key=None, headers={}, **kwargs):
    with open(os.path.join(os.path.dirname(__file__), "emails", template)) as f:
        body = html.parser.HTMLParser().unescape(\
        body = html.parser.HTMLParser().unescape(
            pystache.render(f.read(), {
                'owner-name': owner_name,
                'owner-email': owner_email,

M metasrht/qrcode.py => metasrht/qrcode.py +1 -1
@@ 1,5 1,5 @@
import io
import base64
import io
import qrcode

def gen_qr(data):