Compare commits
No commits in common. "bfc10c5a9682886a7b1ac93bb638e339d5da2707" and "0893c713e4a14243a8d8445ff6108d24ab3867c1" have entirely different histories.
bfc10c5a96
...
0893c713e4
@ -136,20 +136,5 @@ def logout():
|
||||
if g.member is not None:
|
||||
tokens.forget(g.member["id"])
|
||||
session.clear()
|
||||
|
||||
# Deliberately NOT a redirect back to the login page.
|
||||
#
|
||||
# Clearing this session does not touch the Gitea session in the same
|
||||
# browser, and Gitea remembers that this app was authorised. So the next
|
||||
# click on "Entrar con Gitea" gets a code back immediately and signs the
|
||||
# person straight back in without a password — which on a laptop shared
|
||||
# around an association means "Salir" was telling them something untrue.
|
||||
#
|
||||
# Gitea cannot be signed out from here: its logout has been POST-only since
|
||||
# 1.11.2, and a cross-site POST would need Gitea's CSRF token. `prompt=login`
|
||||
# would be the other way round it, and is undocumented in every released
|
||||
# version of Gitea's OAuth2 provider — not something to rest this on.
|
||||
#
|
||||
# So the honest thing is to say so and point at the one place that can
|
||||
# finish the job.
|
||||
return render_template("logged_out.html", gitea_url=current_app.config["GITEA_URL"].rstrip("/"))
|
||||
flash("Sesión cerrada.", "ok")
|
||||
return redirect(url_for("auth.login"))
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
{# Shown instead of bouncing back to the login page, because bouncing back would
|
||||
hide the fact that one click gets you straight in again. #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Sesión cerrada{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<article class="card card--center">
|
||||
<h1>Saliste del área de la comunidad</h1>
|
||||
|
||||
<p class="muted">
|
||||
Tu sesión aquí está cerrada. Pero este navegador <strong>sigue conectado a
|
||||
Gitea</strong>, que es donde se guardan las cuentas — así que quien use
|
||||
este ordenador después podría volver a entrar sin contraseña.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a class="btn" href="{{ gitea_url }}/user/logout">Cerrar sesión también en Gitea</a>
|
||||
</p>
|
||||
|
||||
<p class="muted small">
|
||||
Si esa página no te desconecta, abre el menú de tu perfil en
|
||||
<a href="{{ gitea_url }}">Gitea</a> y elige <em>Sign Out</em>.
|
||||
Cerrar el navegador también sirve.
|
||||
</p>
|
||||
|
||||
<p class="muted small">
|
||||
En tu propio ordenador no hace falta: puedes volver a entrar cuando quieras.
|
||||
</p>
|
||||
|
||||
<p><a class="linkish" href="{{ url_for('auth.login') }}">Volver a entrar</a></p>
|
||||
</article>
|
||||
{% endblock %}
|
||||
@ -106,41 +106,3 @@ def test_login_redirect_cannot_be_pointed_offsite(client, monkeypatch, make_memb
|
||||
def test_responses_say_do_not_index(client):
|
||||
response = client.get("/comunidad/login")
|
||||
assert response.headers["X-Robots-Tag"] == "noindex, nofollow"
|
||||
|
||||
|
||||
def test_logout_says_the_gitea_session_is_still_open(client, db, make_member, sign_in, post):
|
||||
"""Redirecting to the login page would hide the problem: one click on
|
||||
"Entrar con Gitea" signs you straight back in, because Gitea's session and
|
||||
its record of the authorisation both survive."""
|
||||
member_id = make_member("maria")
|
||||
db.execute(
|
||||
"INSERT INTO gitea_tokens (member_id, access_token) VALUES (?, 'tok')",
|
||||
(member_id,),
|
||||
)
|
||||
sign_in(member_id)
|
||||
|
||||
response = post("/comunidad/logout")
|
||||
page = response.get_data(as_text=True)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert "sigue conectado" in page # the warning, not a redirect
|
||||
assert "/user/logout" in page
|
||||
|
||||
with client.session_transaction() as session:
|
||||
assert "member_id" not in session
|
||||
assert db.execute("SELECT 1 FROM gitea_tokens WHERE member_id = ?",
|
||||
(member_id,)).fetchone() is None
|
||||
|
||||
|
||||
def test_logout_leaves_nothing_the_server_can_act_with(client, db, make_member, sign_in, post):
|
||||
"""The token is what lets this server commit as the member. Clearing the
|
||||
cookie without dropping it would end the browser's access but not ours."""
|
||||
member_id = make_member("maria")
|
||||
db.execute(
|
||||
"INSERT INTO gitea_tokens (member_id, access_token) VALUES (?, 'tok')",
|
||||
(member_id,),
|
||||
)
|
||||
sign_in(member_id)
|
||||
post("/comunidad/logout")
|
||||
|
||||
assert db.execute("SELECT COUNT(*) AS n FROM gitea_tokens").fetchone()["n"] == 0
|
||||
|
||||
@ -501,76 +501,3 @@ Not urgent — leaving it costs a folder and one `wget` in the pipeline:
|
||||
1. `rm -rf static/admin/`
|
||||
2. Delete the `wget … decap-cms.js` line from `.woodpecker.yml`
|
||||
3. Delete the `decap-cms` OAuth application in Gitea
|
||||
|
||||
## 12. Make Gitea look like the site
|
||||
|
||||
Members sign in to `/comunidad/` through Gitea, so Gitea's sign-in form and its
|
||||
authorize dialog are part of the journey for everyone — not just for you, and
|
||||
not just for people who open a repository. Unthemed they are two dark screens in
|
||||
the middle of a cream-coloured site.
|
||||
|
||||
How often anyone sees them is worth knowing before judging the result: the
|
||||
**authorize dialog appears once per person, ever** — Gitea remembers the grant —
|
||||
and the **sign-in form only when their Gitea session has lapsed**, which
|
||||
"Remember This Device" pushes out to weeks. This is a first-impression fix.
|
||||
|
||||
Unlike Decap, Gitea supports this properly: a theme is a CSS file in a directory
|
||||
it already reads.
|
||||
|
||||
```sh
|
||||
cd ~/vienalatina
|
||||
git pull --no-rebase --no-edit gitea main
|
||||
bash scripts/gitea-theme.sh
|
||||
```
|
||||
|
||||
Then add the line the script prints to `/srv/gitea/docker-compose.yml` (it is
|
||||
already in `infra/gitea/docker-compose.yml`):
|
||||
|
||||
```
|
||||
- GITEA__ui__DEFAULT_THEME=vienalatina
|
||||
```
|
||||
|
||||
```sh
|
||||
cd /srv/gitea && sudo docker compose up -d
|
||||
```
|
||||
|
||||
Check it in a private window at **https://git.vienalatina.com/user/login** —
|
||||
cream background, the Viena Latina wordmark, `#c0391c` buttons. Then browse a
|
||||
repository and open a commit: a theme that only looks right on the login page is
|
||||
half done.
|
||||
|
||||
### Re-run it after every Gitea upgrade
|
||||
|
||||
The theme is Gitea's own light theme with our colours appended, and the base is
|
||||
read out of the running container so it matches the installed version. A new
|
||||
Gitea release can introduce variables our overrides do not mention, and a base
|
||||
frozen in the repository would drift out of date in ways nobody notices until a
|
||||
page looks wrong.
|
||||
|
||||
```sh
|
||||
bash scripts/gitea-theme.sh
|
||||
cd /srv/gitea && sudo docker compose restart gitea
|
||||
```
|
||||
|
||||
Nothing breaks if you forget — an unknown variable is a declaration nobody
|
||||
reads, so the worst case is a corner that stays grey.
|
||||
|
||||
### Signing out is two steps, and the app says so
|
||||
|
||||
Clicking **Salir** in the members area closes that session and deletes the
|
||||
stored Gitea token. It cannot close the **Gitea** session in the same browser,
|
||||
and Gitea remembers that the app was authorised — so without saying anything,
|
||||
the next click on *Entrar con Gitea* would sign the person straight back in with
|
||||
no password. On a laptop shared around the association, that is a button that
|
||||
lies.
|
||||
|
||||
Gitea cannot be signed out from another site: its logout has been POST-only
|
||||
since 1.11.2, so a link cannot trigger it and a cross-site POST would need
|
||||
Gitea's CSRF token. The `prompt=login` parameter that would force
|
||||
re-authentication is undocumented in every released version of Gitea's OAuth2
|
||||
provider, and a security control should not rest on that.
|
||||
|
||||
So the logout page says plainly what is and is not closed, and offers the link
|
||||
that finishes the job. On a shared computer, use it — or close the browser,
|
||||
which also works. The members-area cookie is already a browser-session cookie,
|
||||
so it does not survive that either way.
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
<!-- Viena Latina wordmark, for Gitea's header and favicon.
|
||||
|
||||
The site has no logo image: its brand is the words "Viena Latina" set in
|
||||
Montserrat 700 at #c0391c
|
||||
(themes/vienalatina/layouts/partials/header.html).
|
||||
|
||||
Set as live text with the same font stack as main.css, rather than traced
|
||||
into paths. That looks like a shortcut and is actually the faithful
|
||||
choice: the site loads no webfont at all — deliberately, so no request
|
||||
leaves the server (GDPR) — so visitors already see this wordmark in
|
||||
whatever sans-serif their machine substitutes. Paths would render a
|
||||
Montserrat that most people never see on the site itself.
|
||||
|
||||
Stacked on two lines because this is also the favicon, where a wide
|
||||
wordmark shrinks to an unreadable smear. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 64" role="img"
|
||||
aria-label="Viena Latina" width="160" height="64">
|
||||
<title>Viena Latina</title>
|
||||
<g fill="#c0391c" font-family="Montserrat, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif"
|
||||
font-weight="700" font-size="27" letter-spacing="-0.4">
|
||||
<text x="4" y="27">Viena</text>
|
||||
<text x="4" y="56">Latina</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@ -23,13 +23,6 @@ services:
|
||||
- GITEA__cors__ALLOW_DOMAIN=https://vienalatina.com
|
||||
- GITEA__cors__METHODS=GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
|
||||
- GITEA__cors__HEADERS=Content-Type,User-Agent,Authorization
|
||||
|
||||
# Members reach /comunidad/ through Gitea's sign-in and authorize
|
||||
# screens, so those are part of the site's journey even for people
|
||||
# who never open a repository. DEFAULT_THEME is what anonymous
|
||||
# visitors get, which is exactly those two pages.
|
||||
# Install the theme first: bash scripts/gitea-theme.sh
|
||||
- GITEA__ui__DEFAULT_THEME=vienalatina
|
||||
volumes:
|
||||
- ./data:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
|
||||
@ -1,98 +0,0 @@
|
||||
/* Viena Latina colours for Gitea.
|
||||
*
|
||||
* Deltas only. scripts/gitea-theme.sh concatenates Gitea's own light theme —
|
||||
* read out of the running container, so it matches the installed version — and
|
||||
* then this file. Shipping the full theme instead would mean a copy of
|
||||
* somebody else's stylesheet going stale in our repository, and an upgrade
|
||||
* turning into a merge.
|
||||
*
|
||||
* Why this exists: members sign in to /comunidad/ through Gitea, so Gitea's
|
||||
* sign-in form and authorize dialog are part of the journey whether or not
|
||||
* anyone ever browses a repository. Unthemed, they are two dark screens in the
|
||||
* middle of a cream-coloured site, and the platform stops feeling like one
|
||||
* thing.
|
||||
*
|
||||
* The values come from themes/vienalatina/assets/css/main.css. If the brand
|
||||
* colours change there, change them here too — Hugo fingerprints its CSS and
|
||||
* Gitea serves this as a static file, so there is no way to share one source.
|
||||
*
|
||||
* Safe failure mode: anything Gitea renames is simply a declaration nobody
|
||||
* reads, and that part keeps the light theme's value. The result of getting a
|
||||
* variable name wrong is a corner that stays grey, not a broken page.
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* Brand — #c0391c, with the darker and lighter steps Gitea expects for
|
||||
hover, active and focus states. */
|
||||
--color-primary: #c0391c;
|
||||
--color-primary-contrast: #ffffff;
|
||||
--color-primary-dark-1: #ad331a;
|
||||
--color-primary-dark-2: #9a2a0f;
|
||||
--color-primary-dark-3: #86240d;
|
||||
--color-primary-dark-4: #731f0b;
|
||||
--color-primary-dark-5: #5f1a09;
|
||||
--color-primary-dark-6: #4c1507;
|
||||
--color-primary-dark-7: #380f05;
|
||||
--color-primary-light-1: #cd5137;
|
||||
--color-primary-light-2: #d66a53;
|
||||
--color-primary-light-3: #de836f;
|
||||
--color-primary-light-4: #e69c8b;
|
||||
--color-primary-light-5: #eeb5a7;
|
||||
--color-primary-light-6: #f6cec3;
|
||||
--color-primary-light-7: #fbe2db;
|
||||
--color-primary-alpha-10: #c0391c1a;
|
||||
--color-primary-alpha-20: #c0391c33;
|
||||
--color-primary-alpha-30: #c0391c4d;
|
||||
--color-primary-alpha-40: #c0391c66;
|
||||
--color-primary-alpha-50: #c0391c80;
|
||||
--color-primary-alpha-60: #c0391c99;
|
||||
--color-primary-alpha-70: #c0391cb3;
|
||||
--color-primary-alpha-80: #c0391ccc;
|
||||
--color-primary-alpha-90: #c0391ce6;
|
||||
--color-primary-hover: #ad331a;
|
||||
--color-primary-active: #9a2a0f;
|
||||
|
||||
/* Page and panels — the site's cream background and white cards. */
|
||||
--color-body: #f8f3ef;
|
||||
--color-box-body: #ffffff;
|
||||
--color-box-body-highlight: #fdf1ed;
|
||||
--color-box-header: #f2ebe6;
|
||||
--color-secondary-bg: #f2ebe6;
|
||||
--color-menu: #ffffff;
|
||||
--color-card: #ffffff;
|
||||
--color-markup-code-block: #f2ebe6;
|
||||
|
||||
/* Type — the same near-black and muted brown the site uses. */
|
||||
--color-text: #1a0d09;
|
||||
--color-text-dark: #1a0d09;
|
||||
--color-text-light: #5c3d37;
|
||||
--color-text-light-1: #6b4a43;
|
||||
--color-text-light-2: #7d5a52;
|
||||
--color-text-light-3: #9a7870;
|
||||
|
||||
/* Borders — warm rather than the default neutral grey, which is most of
|
||||
what makes an unthemed Gitea read as "a different website". */
|
||||
--color-secondary: #e0cec8;
|
||||
--color-secondary-dark-1: #d3bdb6;
|
||||
--color-secondary-light-1: #ebdcd7;
|
||||
--color-light-border: #e0cec8;
|
||||
--color-input-border: #c2a89f;
|
||||
--color-input-background: #ffffff;
|
||||
--color-input-text: #1a0d09;
|
||||
|
||||
/* The top bar, which is the first thing anyone sees. */
|
||||
--color-nav-bg: #ffffff;
|
||||
--color-nav-hover-bg: #fdf1ed;
|
||||
--color-nav-text: #1a0d09;
|
||||
--color-header-wrapper: #ffffff;
|
||||
--color-footer: #f8f3ef;
|
||||
|
||||
--color-accent: #c0391c;
|
||||
--color-small-accent: #fbe2db;
|
||||
}
|
||||
|
||||
/* The wordmark is wide, unlike Gitea's square cup, so it needs room. */
|
||||
.logo {
|
||||
height: 26px !important;
|
||||
width: auto !important;
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install (or reinstall) the Viena Latina theme for Gitea.
|
||||
#
|
||||
# Members sign in to /comunidad/ through Gitea, so Gitea's sign-in form and
|
||||
# authorize dialog are part of the journey whether or not anyone ever browses a
|
||||
# repository. This makes those two screens look like the rest of the platform.
|
||||
#
|
||||
# bash scripts/gitea-theme.sh
|
||||
#
|
||||
# Run it again after every Gitea upgrade. The theme is built by concatenating
|
||||
# Gitea's own light theme with our overrides, so the base has to come from the
|
||||
# version that is actually installed — a new release can add variables, and a
|
||||
# copy frozen in this repository would slowly drift out of date in ways nobody
|
||||
# would notice until a page looked wrong.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GITEA_DIR="${GITEA_DIR:-/srv/gitea}"
|
||||
REPO_DIR="${REPO_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
||||
SERVICE="${SERVICE:-gitea}"
|
||||
|
||||
OVERRIDES="$REPO_DIR/infra/gitea/theme-vienalatina.overrides.css"
|
||||
LOGO="$REPO_DIR/infra/gitea/assets/logo.svg"
|
||||
|
||||
CUSTOM="$GITEA_DIR/data/gitea" # GITEA_CUSTOM inside the container is /data/gitea
|
||||
CSS_DIR="$CUSTOM/public/assets/css"
|
||||
IMG_DIR="$CUSTOM/public/assets/img"
|
||||
|
||||
for file in "$OVERRIDES" "$LOGO"; do
|
||||
[ -f "$file" ] || { echo "Missing $file" >&2; exit 1; }
|
||||
done
|
||||
|
||||
echo "== reading the installed Gitea's light theme"
|
||||
cd "$GITEA_DIR"
|
||||
BASE="$(docker compose exec -T "$SERVICE" \
|
||||
cat /app/gitea/public/assets/css/theme-gitea-light.css)"
|
||||
|
||||
if [ -z "$BASE" ]; then
|
||||
echo "Could not read Gitea's own theme — is the container running?" >&2
|
||||
echo "Check with: cd $GITEA_DIR && docker compose ps" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo mkdir -p "$CSS_DIR" "$IMG_DIR"
|
||||
|
||||
echo "== writing theme-vienalatina.css"
|
||||
{
|
||||
printf '/* Built by scripts/gitea-theme.sh on %s.\n' "$(date -u +%FT%TZ)"
|
||||
printf ' Gitea theme-gitea-light.css + infra/gitea/theme-vienalatina.overrides.css\n'
|
||||
printf ' Do not edit here: rerun the script. */\n'
|
||||
printf '%s\n' "$BASE"
|
||||
cat "$OVERRIDES"
|
||||
} | sudo tee "$CSS_DIR/theme-vienalatina.css" > /dev/null
|
||||
|
||||
echo "== writing the logo and favicon"
|
||||
# logo.svg is the header mark, favicon.svg the tab icon. Gitea also looks for
|
||||
# PNG fallbacks; without them it falls back to its own, which is why the tab
|
||||
# can still show a cup in older browsers. Converting needs a tool this box does
|
||||
# not have, and an SVG favicon covers everything current.
|
||||
sudo cp "$LOGO" "$IMG_DIR/logo.svg"
|
||||
sudo cp "$LOGO" "$IMG_DIR/favicon.svg"
|
||||
|
||||
sudo chown -R 1000:1000 "$CUSTOM/public"
|
||||
|
||||
echo
|
||||
echo "Installed. Now make it the default (once):"
|
||||
echo " add GITEA__ui__DEFAULT_THEME=vienalatina to $GITEA_DIR/docker-compose.yml"
|
||||
echo " then cd $GITEA_DIR && sudo docker compose up -d"
|
||||
echo
|
||||
echo "Already set? A restart is enough to pick up the new file:"
|
||||
echo " cd $GITEA_DIR && sudo docker compose restart $SERVICE"
|
||||
Loading…
Reference in New Issue
Block a user