1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-29 19:26:16 +00:00

Adjsut terminology and add MOTDs

This commit is contained in:
osmarks 2024-10-24 10:06:44 +01:00
parent 55d8dbd7be
commit 1fbef60857
10 changed files with 36 additions and 157 deletions

View File

@ -1,13 +1,11 @@
package auth
import (
"errors"
"fmt"
"io"
"log"
"mime"
"net/http"
"strings"
"github.com/bouncepaw/mycorrhiza/viewutil"
@ -29,9 +27,7 @@ func InitAuth(r *mux.Router) {
if cfg.AllowRegistration {
r.HandleFunc("/register", handlerRegister).Methods(http.MethodPost, http.MethodGet)
}
if cfg.TelegramEnabled {
r.HandleFunc("/telegram-login", handlerTelegramLogin)
}
r.HandleFunc("/login", handlerLogin)
r.HandleFunc("/logout", handlerLogout)
}
@ -152,74 +148,3 @@ func handlerLogin(w http.ResponseWriter, rq *http.Request) {
http.Redirect(w, rq, "/", http.StatusSeeOther)
}
}
func handlerTelegramLogin(w http.ResponseWriter, rq *http.Request) {
// Note there is no lock here.
lc := l18n.FromRequest(rq)
w.Header().Set("Content-Type", "text/html;charset=utf-8")
rq.ParseForm()
var (
values = rq.URL.Query()
username = strings.ToLower(values.Get("username"))
seemsValid = user.TelegramAuthParamsAreValid(values)
err = user.Register(
username,
"", // Password matters not
"editor",
"telegram",
false,
)
)
// If registering a user via Telegram failed, because a Telegram user with this name
// has already registered, then everything is actually ok!
if user.HasUsername(username) && user.ByName(username).Source == "telegram" {
err = nil
}
if !seemsValid {
err = errors.New("Wrong parameters")
}
if err != nil {
log.Printf("Failed to register %s using Telegram: %s", username, err.Error())
w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString(
w,
viewutil.Base(
viewutil.MetaFrom(w, rq),
lc.Get("ui.error"),
fmt.Sprintf(
`<main class="main-width"><p>%s</p><p>%s</p><p><a href="/login">%s<a></p></main>`,
lc.Get("auth.error_telegram"),
err.Error(),
lc.Get("auth.go_login"),
),
map[string]string{},
),
)
return
}
errmsg := user.LoginDataHTTP(w, username, "")
if errmsg != nil {
log.Printf("Failed to login %s using Telegram: %s", username, err.Error())
w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString(
w,
viewutil.Base(
viewutil.MetaFrom(w, rq),
"Error",
fmt.Sprintf(
`<main class="main-width"><p>%s</p><p>%s</p><p><a href="/login">%s<a></p></main>`,
lc.Get("auth.error_telegram"),
err.Error(),
lc.Get("auth.go_login"),
),
map[string]string{},
),
)
return
}
log.Printf("Authorize %s from Telegram", username)
http.Redirect(w, rq, "/", http.StatusSeeOther)
}

View File

@ -46,6 +46,8 @@ var (
ReplaceFrom []string
ReplaceTo []string
Motds []string
)
// WikiDir is a full path to the wiki storage directory, which also must be a
@ -64,6 +66,7 @@ type Config struct {
Telegram `comment:"You can enable Telegram authorization. Follow these instructions: https://core.telegram.org/widgets/login#setting-up-a-bot"`
ReplaceFrom []string
ReplaceTo []string
Motds []string
}
// Hyphae is a section of Config which has fields related to special hyphae.
@ -153,17 +156,17 @@ func ReadConfigFile(path string) error {
// Save the default configuration
err = f.ReflectFrom(cfg)
if err != nil {
return fmt.Errorf("Failed to serialize the config: %w", err)
return fmt.Errorf("failed to serialize the config: %w", err)
}
// Disable key-value auto-aligning, but retain spaces around '=' sign
ini.PrettyFormat = false
ini.PrettyEqual = true
if err = f.SaveTo(path); err != nil {
return fmt.Errorf("Failed to save the config file: %w", err)
return fmt.Errorf("failed to save the config file: %w", err)
}
} else {
return fmt.Errorf("Failed to open the config file: %w", err)
return fmt.Errorf("failed to open the config file: %w", err)
}
}
@ -198,6 +201,7 @@ func ReadConfigFile(path string) error {
TelegramEnabled = (TelegramBotToken != "") && (TelegramBotName != "")
ReplaceFrom = cfg.ReplaceFrom
ReplaceTo = cfg.ReplaceTo
Motds = cfg.Motds
// This URL makes much more sense. If no URL is set or the protocol is forgotten, assume HTTP.
if URL == "" {

View File

@ -1,4 +1,4 @@
{{define "list of hyphae"}}List of hyphae{{end}}
{{define "list of hyphae"}}List of pages{{end}}
{{define "title"}}{{template "list of hyphae"}}{{end}}
{{define "body"}}
<main class="main-width">

View File

@ -1,25 +1,2 @@
User-agent: *
Allow: /help/
Allow: /hypha/
Allow: /recent-changes
Allow: /list
Disallow: /page/
Disallow: /admin/
Disallow: /lock
Disallow: /text/
Disallow: /binary/
Disallow: /rev/
Disallow: /rev-text/
Disallow: /primitive-diff/
Disallow: /media/
Disallow: /edit/
Disallow: /delete/
Disallow: /rename/
Disallow: /remove-media/
Disallow: /history/
Disallow: /orphans
Disallow: /random
Disallow: /title-search/
Disallow: /backlinks/
Disallow: /user-list
Crawl-delay: 5
Allow: /

View File

@ -290,24 +290,24 @@ function openHelp() {
rrh.shortcuts.addGroup(new ShortcutGroup('Common', null, [
new Shortcut('g', $$('.top-bar__highlight-link'), 'First 9 header links'),
new Shortcut('g h', '/', 'Home'),
new Shortcut('g l', '/list/', 'List of hyphae'),
new Shortcut('g l', '/list/', 'List of page'),
new Shortcut('g r', '/recent-changes/', 'Recent changes'),
new Shortcut('g u', $('.auth-links__user-link'), 'Your profiles hypha'),
new Shortcut('g u', $('.auth-links__user-link'), 'Your profiles page'),
new Shortcut(['?', isMac ? 'Meta+/' : 'Ctrl+/'], openHelp, 'Shortcut help', { force: true }),
]))
if (document.body.dataset.rrhAddr.startsWith('/hypha')) {
rrh.shortcuts.addGroup(new ShortcutGroup('Hypha', null, [
new Shortcut('', $$('article .wikilink'), 'First 9 hyphas links'),
new Shortcut(['p', 'Alt+ArrowLeft', 'Ctrl+Alt+ArrowLeft'], $('.prevnext__prev'), 'Previous hypha'),
new Shortcut(['n', 'Alt+ArrowRight', 'Ctrl+Alt+ArrowRight'], $('.prevnext__next'), 'Next hypha'),
new Shortcut(['s', 'Alt+ArrowUp', 'Ctrl+Alt+ArrowUp'], $$('.navi-title a').slice(1, -1).slice(-1)[0], 'Parent hypha'),
new Shortcut(['c', 'Alt+ArrowDown', 'Ctrl+Alt+ArrowDown'], $('.subhyphae__link'), 'First child hypha'),
new Shortcut(['e', isMac ? 'Meta+Enter' : 'Ctrl+Enter'], $('.btn__link_navititle[href^="/edit/"]'), 'Edit this hypha'),
new Shortcut('v', $('.hypha-info__link[href^="/hypha/"]'), 'Go to hyphas page'),
rrh.shortcuts.addGroup(new ShortcutGroup('Page', null, [
new Shortcut('', $$('article .wikilink'), 'First 9 pages links'),
new Shortcut(['p', 'Alt+ArrowLeft', 'Ctrl+Alt+ArrowLeft'], $('.prevnext__prev'), 'Previous page'),
new Shortcut(['n', 'Alt+ArrowRight', 'Ctrl+Alt+ArrowRight'], $('.prevnext__next'), 'Next page'),
new Shortcut(['s', 'Alt+ArrowUp', 'Ctrl+Alt+ArrowUp'], $$('.navi-title a').slice(1, -1).slice(-1)[0], 'Parent page'),
new Shortcut(['c', 'Alt+ArrowDown', 'Ctrl+Alt+ArrowDown'], $('.subhyphae__link'), 'First child page'),
new Shortcut(['e', isMac ? 'Meta+Enter' : 'Ctrl+Enter'], $('.btn__link_navititle[href^="/edit/"]'), 'Edit this page'),
new Shortcut('v', $('.hypha-info__link[href^="/hypha/"]'), 'Go to page overview'),
new Shortcut('a', $('.hypha-info__link[href^="/media/"]'), 'Go to media management'),
new Shortcut('h', $('.hypha-info__link[href^="/history/"]'), 'Go to history'),
new Shortcut('r', $('.hypha-info__link[href^="/rename/"]'), 'Rename this hypha'),
new Shortcut('r', $('.hypha-info__link[href^="/rename/"]'), 'Rename this page'),
new Shortcut('b', $('.hypha-info__link[href^="/backlinks/"]'), 'Backlinks'),
]))
}

View File

@ -1,15 +1,10 @@
package user
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"log"
"net/http"
"sort"
"strings"
"time"
"golang.org/x/crypto/bcrypt"
@ -123,35 +118,3 @@ func cookie(nameSuffix, val string, t time.Time) *http.Cookie {
Path: "/",
}
}
// TelegramAuthParamsAreValid is true if the given params are ok.
func TelegramAuthParamsAreValid(params map[string][]string) bool {
// According to the Telegram documentation,
// > You can verify the authentication and the integrity of the data received by comparing the received hash parameter with the hexadecimal representation of the HMAC-SHA-256 signature of the data-check-string with the SHA256 hash of the bot's token used as a secret key.
tokenHash := sha256.New()
tokenHash.Write([]byte(cfg.TelegramBotToken))
secretKey := tokenHash.Sum(nil)
hash := hmac.New(sha256.New, secretKey)
hash.Write([]byte(telegramDataCheckString(params)))
hexHash := hex.EncodeToString(hash.Sum(nil))
passedHash := params["hash"][0]
return passedHash == hexHash
}
// According to the Telegram documentation,
// > Data-check-string is a concatenation of all received fields, sorted in alphabetical order, in the format key=<value> with a line feed character ('\n', 0x0A) used as separator e.g., 'auth_date=<auth_date>\nfirst_name=<first_name>\nid=<id>\nusername=<username>'.
//
// Note that hash is not used here.
func telegramDataCheckString(params map[string][]string) string {
var lines []string
for key, value := range params {
if key == "hash" {
continue
}
lines = append(lines, fmt.Sprintf("%s=%s", key, value[0]))
}
sort.Strings(lines)
return strings.Join(lines, "\n")
}

View File

@ -3,10 +3,12 @@ package util
import (
"crypto/rand"
"encoding/hex"
"github.com/bouncepaw/mycorrhiza/files"
"log"
"net/http"
"strings"
"time"
"github.com/bouncepaw/mycorrhiza/files"
"git.sr.ht/~bouncepaw/mycomarkup/v5/util"
"github.com/bouncepaw/mycorrhiza/cfg"
@ -154,3 +156,9 @@ func IsRevHash(revHash string) bool {
}
return true
}
func GetMotd() string {
now := time.Now().UTC().Unix()
dayIndex := now / 86400
return cfg.Motds[dayIndex%int64(len(cfg.Motds))]
}

View File

@ -17,8 +17,8 @@
<body data-rrh-addr="{{if .Addr}}{{.Addr}}{{else}}{{.Meta.Addr}}{{end}}"{{range $key, $value := .BodyAttributes}} data-rrh-{{$key}}="{{$value}}"{{end}}>
<header>
<div class="logo">
<img src="/static/favicon.ico" alt="A picture of Euler, stretched into a square" />
<div class="ominous"><span>It's already far too late.</span></div>
<img src="/static/favicon.ico" alt="A picture of mathematician Leonhard Euler, stretched into a square" />
<div class="ominous"><span>{{.Motd}}</span></div>
</div>
<nav class="main-width top-bar">
<ul class="top-bar__wrapper">

View File

@ -100,6 +100,7 @@ type BaseData struct {
Title string // TODO: remove
Body string // TODO: remove
BodyAttributes map[string]string
Motd string
}
func (bd *BaseData) withBaseValues(meta Meta, headerLinks []HeaderLink, commonScripts []string) {
@ -123,6 +124,7 @@ func Base(meta Meta, title, body string, bodyAttributes map[string]string, headE
EditScripts: cfg.EditScripts,
Body: body,
BodyAttributes: bodyAttributes,
Motd: util.GetMotd(),
})
if err != nil {
log.Println(err)

View File

@ -7,7 +7,6 @@ import (
"net/url"
"github.com/bouncepaw/mycorrhiza/admin"
"github.com/bouncepaw/mycorrhiza/settings"
"github.com/bouncepaw/mycorrhiza/auth"
"github.com/bouncepaw/mycorrhiza/backlinks"
"github.com/bouncepaw/mycorrhiza/categories"
@ -16,6 +15,7 @@ import (
"github.com/bouncepaw/mycorrhiza/hypview"
"github.com/bouncepaw/mycorrhiza/interwiki"
"github.com/bouncepaw/mycorrhiza/misc"
"github.com/bouncepaw/mycorrhiza/settings"
"github.com/gorilla/mux"
@ -31,7 +31,7 @@ func Handler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
w.Header().Add("Content-Security-Policy",
"default-src 'self' telegram.org *.telegram.org; "+
"default-src 'self'; "+
"img-src * data:; media-src *; style-src *; font-src * data:")
next.ServeHTTP(w, rq)
})