From b1d4d28e608571c9cae93f4c8d1579e1c2f4f4a6 Mon Sep 17 00:00:00 2001 From: Will Norris Date: Tue, 2 Apr 2024 09:34:16 -0700 Subject: [PATCH] add support for running in read-only mode Right now, running in read-only mode displays a banner stating that links can be resolved but not created or updated, as well as actively blocking requests to modify links. Update #118 Signed-off-by: Will Norris --- golink.go | 30 ++++++++++++++++++++++-------- static/base.css | 15 +++++++++++++++ tailwind.config.js | 32 +++++++++++++++++++++----------- tmpl/home.html | 34 +++++++++++++++++++--------------- 4 files changed, 77 insertions(+), 34 deletions(-) diff --git a/golink.go b/golink.go index 298eb86..263079f 100644 --- a/golink.go +++ b/golink.go @@ -64,6 +64,7 @@ var ( hostname = flag.String("hostname", defaultHostname, "service name") resolveFromBackup = flag.String("resolve-from-backup", "", "resolve a link from snapshot file and exit") allowUnknownUsers = flag.Bool("allow-unknown-users", false, "allow unknown users to save links") + readonly = flag.Bool("readonly", false, "start golink server in read-only mode") ) var stats struct { @@ -269,10 +270,11 @@ type visitData struct { // homeData is the data used by homeTmpl. type homeData struct { - Short string - Long string - Clicks []visitData - XSRF string + Short string + Long string + Clicks []visitData + XSRF string + ReadOnly bool } // deleteData is the data used by deleteTmpl. @@ -443,10 +445,11 @@ func serveHome(w http.ResponseWriter, r *http.Request, short string) { return } homeTmpl.Execute(w, homeData{ - Short: short, - Long: long, - Clicks: clicks, - XSRF: xsrftoken.Generate(xsrfKey, cu.login, newShortName), + Short: short, + Long: long, + Clicks: clicks, + XSRF: xsrftoken.Generate(xsrfKey, cu.login, newShortName), + ReadOnly: *readonly, }) } @@ -743,6 +746,10 @@ func userExists(ctx context.Context, login string) (bool, error) { var reShortName = regexp.MustCompile(`^\w[\w\-\.]*$`) func serveDelete(w http.ResponseWriter, r *http.Request) { + if *readonly { + http.Error(w, "golink is in read-only mode", http.StatusMethodNotAllowed) + return + } short := strings.TrimPrefix(r.URL.Path, "/.delete/") if short == "" { http.Error(w, "short required", http.StatusBadRequest) @@ -793,6 +800,10 @@ func serveDelete(w http.ResponseWriter, r *http.Request) { // long URL are validated for proper format. Existing links may only be updated // by their owner. func serveSave(w http.ResponseWriter, r *http.Request) { + if *readonly { + http.Error(w, "golink is in read-only mode", http.StatusMethodNotAllowed) + return + } short, long := r.FormValue("short"), r.FormValue("long") if short == "" || long == "" { http.Error(w, "short and long required", http.StatusBadRequest) @@ -871,6 +882,9 @@ func serveSave(w http.ResponseWriter, r *http.Request) { // Admin users can edit all links. // Non-admin users can only edit their own links or links without an active owner. func canEditLink(ctx context.Context, link *Link, u user) bool { + if *readonly { + return false + } if link == nil || link.Owner == "" { // new or unowned link return true diff --git a/static/base.css b/static/base.css index 7915c05..c7c5bcd 100644 --- a/static/base.css +++ b/static/base.css @@ -1351,6 +1351,11 @@ select { border-color: rgb(178 45 48 / var(--tw-border-opacity)); } +.border-orange-50 { + --tw-border-opacity: 1; + border-color: rgb(254 227 192 / var(--tw-border-opacity)); +} + .bg-gray-100 { --tw-bg-opacity: 1; background-color: rgb(247 245 244 / var(--tw-bg-opacity)); @@ -1366,6 +1371,11 @@ select { background-color: rgb(178 45 48 / var(--tw-bg-opacity)); } +.bg-orange-0 { + --tw-bg-opacity: 1; + background-color: rgb(255 250 238 / var(--tw-bg-opacity)); +} + .p-2 { padding: 0.5rem; } @@ -1390,6 +1400,11 @@ select { padding-bottom: 1rem; } +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + .pt-6 { padding-top: 1.5rem; } diff --git a/tailwind.config.js b/tailwind.config.js index 746237b..509e19e 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -41,26 +41,36 @@ module.exports = { 800: "rgba(90, 0, 0)", 900: "rgba(66, 0, 0)", }, - white: '#fff', - current: 'currentColor', + orange: { + 0: "rgba(255, 250, 238)", + 50: "rgba(254, 227, 192)", + 100: "rgba(248, 184, 134)", + 200: "rgba(245, 146, 94)", + 300: "rgba(229, 111, 74)", + 400: "rgba(196, 76, 52)", + 500: "rgba(158, 47, 40)", + 600: "rgba(126, 30, 35)", + 700: "rgba(93, 22, 27)", + 800: "rgba(66, 14, 17)", + 900: "rgba(66, 14, 17)", + }, + white: "#fff", + current: "currentColor", }, extend: { typography: { DEFAULT: { css: { - 'code::before': { - 'content': '', + "code::before": { + content: "", }, - 'code::after': { - 'content': '', + "code::after": { + content: "", }, }, }, }, }, }, - plugins: [ - require('@tailwindcss/forms'), - require('@tailwindcss/typography'), - ], -} + plugins: [require("@tailwindcss/forms"), require("@tailwindcss/typography")], +}; diff --git a/tmpl/home.html b/tmpl/home.html index 64e2267..52dd2ca 100644 --- a/tmpl/home.html +++ b/tmpl/home.html @@ -1,21 +1,25 @@ {{ define "main" }} -

Create a new link

+ {{ if .ReadOnly }} +

golink is running in read-only mode. Links can be resolved, but not created or updated.

+ {{ else }} +

Create a new link

- {{ with .Long }} -

Did you mean {{.}} ? Create a go link for it now:

+ {{ with .Long }} +

Did you mean {{.}} ? Create a go link for it now:

+ {{ end }} +
+ +
+ + + +
+ + +
+

Help and advanced options

{{ end }} -
- -
- - - -
- - -
-

Help and advanced options

Popular Links