Groundwork for unified sr.ht configuration

This commit is contained in:
Drew DeVault 2018-09-02 17:48:59 -04:00
parent ad06e6949f
commit 70e75e96dc
7 changed files with 52 additions and 42 deletions

View File

@ -1,36 +1,36 @@
from configparser import ConfigParser
from werkzeug.local import LocalProxy
config = None
_config = None
_throw = 1
def load_config(name, paths=None):
global config
config = ConfigParser()
if paths == None:
paths = [ "config.ini", "/etc/sr.ht/{}.ini".format(name) ]
config = LocalProxy(lambda: _config)
def load_config():
global _config
_config = ConfigParser()
paths = ["config.ini", "/etc/sr.ht/config.ini"]
for path in paths:
try:
with open(path) as f:
config.read_file(f)
_config.read_file(f)
except FileNotFoundError:
pass
def loaded():
return config != None
_throw = 1
load_config()
def cfg(section, key, default=_throw):
if not config:
return None
v = config.get(section, key) if section in config and key in config[section] else None
if not v:
if default is _throw:
raise Exception("Config option [{}] {} not found".format(section, key))
return v
if _config:
if section in _config and key in _config[section]:
return _config.get(section, key)
if default is _throw:
raise Exception("Config option [{}] {} not found".format(
section, key))
return default
def cfgi(section, key, default=_throw):
return int(cfg(section, key, default))
def cfgkeys(section):
for key in config[section]:
for key in _config[section]:
yield key

View File

@ -14,7 +14,7 @@ smtp_port = cfgi("mail", "smtp-port", default=None)
smtp_user = cfg("mail", "smtp-user", default=None)
smtp_password = cfg("mail", "smtp-password", default=None)
smtp_from = cfg("mail", "smtp-from", default=None)
meta_url = cfg("network", "meta")
meta_url = cfg("meta.sr.ht", "origin")
def lookup_key(user, oauth_token):
"""

View File

@ -3,7 +3,7 @@ from flask import current_app, g
from flask_login import LoginManager, current_user
from functools import wraps
from enum import Enum
from srht.config import cfg, cfgi, cfgkeys
from srht.config import cfg, cfgi, cfgkeys, config
from srht.validation import Validation
from srht.database import db
from srht.markdown import markdown
@ -94,7 +94,7 @@ class LoginConfig:
self.base_scopes = base_scopes
def oauth_url(self, return_to, scopes=[]):
meta_sr_ht = cfg("network", "meta")
meta_sr_ht = cfg("meta.sr.ht", "origin")
return "{}/oauth/authorize?client_id={}&scopes={}&state={}".format(
meta_sr_ht, self.client_id, ','.join(self.base_scopes + scopes),
quote_plus(return_to))
@ -131,12 +131,12 @@ class SrhtFlask(Flask):
self.jinja_env.globals['pagination'] = pagination
self.jinja_env.globals['icon'] = icon
self.jinja_loader = ChoiceLoader(choices)
self.secret_key = cfg("server", "secret-key")
self.secret_key = cfg("sr.ht", "secret-key")
self.login_manager = LoginManager()
self.login_manager.init_app(self)
self.login_manager.anonymous_user = lambda: None
self.login_config = None
self.login_config = login_config
@self.teardown_appcontext
def expire_db(err):
@ -167,9 +167,8 @@ class SrhtFlask(Flask):
user_class = (current_user._get_current_object().__class__
if current_user else None)
ctx = {
'root': cfg("server", "protocol") + "://" + cfg("server", "domain"),
'domain': cfg("server", "domain"),
'protocol': cfg("server", "protocol"),
'root': cfg(self.site, "origin"),
'domain': urlparse(cfg(self.site, "origin")).netloc,
'app': self,
'len': len,
'any': any,
@ -182,6 +181,7 @@ class SrhtFlask(Flask):
'valid': Validation(request),
'site': site,
'site_name': cfg("sr.ht", "site-name", default=None),
'network': self.get_network(),
'history': self.get_site_history(),
'current_user': (user_class.query
.filter(user_class.id == current_user.id)
@ -230,6 +230,9 @@ class SrhtFlask(Flask):
meta_client_id, meta_client_secret, base_scopes)
self.register_blueprint(oauth_blueprint)
def get_network(self):
return [s for s in config if s.endswith(".sr.ht")]
def get_site_history(self):
history = request.cookies.get("history")
if history:
@ -242,9 +245,10 @@ class SrhtFlask(Flask):
history = []
else:
history = []
history = [h for h in history if cfg("network", h, default=None)]
defaults = cfgkeys("network")
ndefaults = len(list(cfgkeys("network")))
history = [h for h in history if h in config]
defaults = self.get_network()
ndefaults = len(defaults)
defaults = iter(defaults)
try:
while len(history) < 5 or ndefaults > len(history):
n = next(defaults)
@ -274,8 +278,7 @@ class SrhtFlask(Flask):
response = super(SrhtFlask, self).make_response(response)
history = self.get_site_history()
history = [self.site] + [h for h in history if h != self.site]
response.set_cookie(
"history",
json.dumps(history),
domain="." + ".".join(cfg("server", "domain").split('.')[1:]))
domain = urlparse(cfg(self.site, "origin")).netloc
response.set_cookie("history", json.dumps(history),
domain="." + ".".join(domain.split('.')[1:]))
return response

View File

@ -178,7 +178,7 @@ def meta_delegated_exchange(token, client_id, client_secret, revocation_url):
meta.sr.ht's responses: token, profile. Raises an OAuthError if anything
goes wrong.
"""
meta_uri = cfg("network", "meta")
meta_uri = cfg("meta.sr.ht", "origin")
try:
r = requests.post("{}/oauth/token/{}".format(meta_uri, token), json={
"client_id": client_id,
@ -224,7 +224,7 @@ def oauth_callback():
return render_template("oauth-error.html",
details=("Expected an exchange token from meta.sr.ht. " +
"Something odd has happened, try again."))
meta_uri = cfg("network", "meta")
meta_uri = cfg("meta.sr.ht", "origin")
r = requests.post(meta_uri + "/oauth/exchange", json={
"client_id": current_app.login_config.client_id,
"client_secret": current_app.login_config.client_secret,

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M576 24v127.984c0 21.461-25.96 31.98-40.971 16.971l-35.707-35.709-243.523 243.523c-9.373 9.373-24.568 9.373-33.941 0l-22.627-22.627c-9.373-9.373-9.373-24.569 0-33.941L442.756 76.676l-35.703-35.705C391.982 25.9 402.656 0 424.024 0H552c13.255 0 24 10.745 24 24zM407.029 270.794l-16 16A23.999 23.999 0 0 0 384 303.765V448H64V128h264a24.003 24.003 0 0 0 16.97-7.029l16-16C376.089 89.851 365.381 64 344 64H48C21.49 64 0 85.49 0 112v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V287.764c0-21.382-25.852-32.09-40.971-16.97z"/></svg>

After

Width:  |  Height:  |  Size: 605 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
{% block title %}
<title>sr.ht {{site}}</title>
<title>{{site}}</title>
{% endblock %}
{% block favicon %}
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QIGCC8n92KyhQAAAj1QTFRFAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////anIwUQAAAL50Uk5TAAECAwQFBgcICQoLDA4PEBESExQVFhcYGRobHB0eHyAhIyQmJygpKistLzAzNDU2Nzg5Ozw9QEFDREZHSElLTE1OT1BRVFdYWVpbXF1eX2BhZGZnaGltbnBxdHV3eHp7fn+AgYKDhIWGh4iJio2TlJucnqGio6Smp6ipqqusrbCxsrO0tre4ury9vr/Cw8TFxsfIycrMzc7P0dLT1dbY2dvf4OLj5OXm5+jq6+zt7u/w8fL09fb3+Pn6+/z9/gNzyOkAAAABYktHRL6k3IPDAAAFwUlEQVQYGe3B+VtUVQAG4G9i0TQZZyA1S0JxydzDNFTUqXBfcylzS8UE21TMyjAQUQnFEi0BHQU3cAc0UGbm+9v65Zw7y70zc++dc3qenof3xZAhQ4b8T+V/uGn/kdrm1psdHTdbm2uP7Ns434//yLD5e+u7aOH+6T0ludBszGf1L5jC87rNBdDm9XXnw0wrfG71cOhQ9N0z2vTk20Ko9t5PYToQOj4FKr17IkKHwtUToMobVQN0of/rkVDik7t06c5yZC7/V1rqajq6f9vKQFlZYNW2A0cvdNPSL35kaPEDmgxerFiSjwQFZQebQzTpKkUmsg4xUX/Nijwk4V15aoAJIhVZcM13ngnatuQhJe/WNiY464VLE28xXsMCD9LyLDzLeMEiuDLzIeM0zIRNs88xTvcMuFDSx1htC+FA6XXG6pkLx0qeM8aLHdlwJGfnP4zRNw8OzexjjOaJcGzSn4zR8z4cmfiQUZF9WXAhuyLCqO4iOOC7xahni+BSWQ+jgl7YlnWeUR3FcG1qJ6MasmDXIUZdexMZGNvGqAOwaTGjrnqREd/fNERKYUvBAxqueZEhXzsNXX7Y8SsNHW8iY+M6afgZNnxKw7NiKDCtl4YA0nrjHqXIIiixjIY7I5FOFQ37oEglDZVIo+glpeYsKJJ9mdJAIVI7QenFRChT3E+pGim9F6G0AwrtohSeglR+otSWDYVygpSqkUJRmNJCKLWEUmgCkvuOUgPU8vxO6TCSev0ZpZlQ7ANKj4YhmXWUGqBcI6UVSOY8pQVQbhGlM0hiTJhCmwfKeW5QCPlh7TNKW6DBdkobYa2eQn8eNPC9pPAbLA17QaEGWtRS6MuBlfmUVkCLtZTmwspeCoN50MIXprATVuopXIQmLRROwUoXhQpoUkXhNizkU1oCTZZRyoPZh5Tyock4SnNgtolCF3TxPKKwBmb7KTRBm0sUdsPsCIWj0OY4hR9gVkthP7SppHASZs0UtkGbLyg0wqyVwkpos4FCC8xuUghAm3IK7TDroFAGbQIUgjDroFAGbQIUgjC7SSEAbcoptMOslcIqaLOBQgvMmilsgzY7KDTCrJbCAWhTReEkzI5QOAptfqTwPcz2UbgAbS5R2AWzjRS6oYvnMYXVMJtPqQCavEVpNsz8lMqgyXJKo2DhPoWD0OQwhU5YOU2hGZpcoVADK3sohLzQwh+h8CWslFBaCS3WUZoDK7nPKZyCFnUUerNh6TSFAS808L+iUANrmylthQafU1oPawVhCm0eKOcJUhgcjSTOUVoI5RZTqkMyqymdhXJNlMqRzPAnlGZDsRJKD3OR1LeUzkEtTxOlSiRXGKL0EZRaSmlwPFI4Tul6DhTKvUXpGFKZEqa0EwrtoRQqRkrVlP6ZBGUmD1A6htQm9FP6IxuK5Fyl1P8O0viahgoo8g0NB5HOyDuUImVQ4mMabo9AWgEaeqZCgel9NCyFDb/Q0DkWGXv7Lg0nYIe/i4Y2HzKUf4OGe6NhS2mEhr98yEh+Kw3hBbCpglHt45CB8TcY9RXsyjrLqM5pcG36XUadfg22eYOM6l0Glz7uY9T1UXCg6AFjHMqGCznfMMb9Qjgyo4cxLhfDsclXGePpdDg0r48x+nflwJHcPQOM0TsLjs3rYazgEtjnWXqLsZ7Oggszuhnn9w9gU0kT49yfDleKgozXuMiDtDyLmxjveiFc8jYwwY3tPqTk/zzIBPWj4FpWRYQJXtau9SEJ/7q6V0wQ/uo1ZKK0iybhlqplYxHP89byw1ciNLm3ABny/0xLjy4dr/xiQ3kgUL5hR9WPlx7T0onRyFzgDl26vRRKjKwcoAv9B0dAlcLqMB0KH3sHKk2pDtGBwWPFUG3C4Ue06WHleOgwbMWZENMarCvPhTb+jb/1MYXemvWjoVnO3J2nbtNCZ82Xc7LxH8mbs2b3DycbW9qDwfaWxpPf71o9exSGDBky5P/pX9F6dsCMuJp+AAAAAElFTkSuQmCC" />
@ -23,13 +23,16 @@
<nav class="navbar navbar-light navbar-expand-sm">
<a class="navbar-brand" href="/">
{{site_name}}
<span class="text-danger">{{site}}</span>
<span class="text-danger">{{site.split(".")[0]}}</span>
</a>
<ul class="navbar-nav mr-auto d-none d-sm-flex">
{% for _site in history %}
{% if _site != site %}
<li class="nav-item">
<a class="nav-link" href="{{cfg("network", _site)}}">{{_site}}</a>
<a
class="nav-link"
href="{{cfg(_site, "origin")}}"
>{{_site.split(".")[0]}}</a>
</li>
{% endif %}
{% endfor %}
@ -38,20 +41,22 @@
{% if current_user %}
<span class="navbar-text">
Logged in as
<a href="{{cfg("network", "meta")}}/profile">{{current_user.username}}</a>
<a href="{{cfg("meta.sr.ht", "origin")}}/profile">
{{current_user.username}}
</a>
&mdash;
<a href="/logout">Log out</a>
</span>
{% else %}
<span class="navbar-text">
{% if site == 'meta' %}
{% if site == 'meta.sr.ht' %}
<a href="/login">Log in</a>
&mdash;
<a href="/">Register</a>
{% else %}
<a href="{{ oauth_url }}">Log in</a>
&mdash;
<a href="{{cfg("network", "meta")}}">Register</a>
<a href="{{cfg("meta.sr.ht", "origin")}}">Register</a>
{% endif %}
</span>
{% endif %}