apps/quotes/handlers_web.go 3.9 K raw
1
package main
2
3
import (
4
	"net/http"
5
	"strings"
6
7
	"github.com/stevedylandev/andromeda/pkg/auth"
8
	"github.com/stevedylandev/andromeda/pkg/web"
9
)
10
11
func quoteToView(q Quote) quoteView {
12
	v := quoteView{Text: q.Text, Author: q.Author}
13
	if q.Source != nil {
14
		v.Source = *q.Source
15
	}
16
	return v
17
}
18
19
func quoteToRow(q Quote) adminQuoteRow {
20
	r := adminQuoteRow{ShortID: q.ShortID, Text: q.Text, Author: q.Author}
21
	if q.Source != nil {
22
		r.Source = *q.Source
23
	}
24
	return r
25
}
26
27
func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) {
28
	data := indexPageData{BaseURL: a.BaseURL}
29
	if q, err := quoteOfTheDay(a.DB); err != nil {
30
		a.Log.Error("quote of the day", "err", err)
31
	} else if q != nil {
32
		v := quoteToView(*q)
33
		data.Quote = &v
34
	}
35
	web.Render(a.Templates, w, "index.html", data, a.Log)
36
}
37
38
func (a *App) randomHandler(w http.ResponseWriter, r *http.Request) {
39
	data := indexPageData{BaseURL: a.BaseURL}
40
	if q, err := randomQuote(a.DB); err != nil {
41
		a.Log.Error("random quote", "err", err)
42
	} else if q != nil {
43
		v := quoteToView(*q)
44
		data.Quote = &v
45
	}
46
	web.Render(a.Templates, w, "index.html", data, a.Log)
47
}
48
49
func (a *App) loginGetHandler(w http.ResponseWriter, r *http.Request) {
50
	web.Render(a.Templates, w, "login.html", loginPageData{Error: r.URL.Query().Get("error")}, a.Log)
51
}
52
53
func (a *App) loginPostHandler(w http.ResponseWriter, r *http.Request) {
54
	if a.AdminPassword == "" {
55
		web.RedirectWithError(w, r, "/admin/login", "No admin password configured")
56
		return
57
	}
58
	if err := r.ParseForm(); err != nil {
59
		web.RedirectWithError(w, r, "/admin/login", "Bad request")
60
		return
61
	}
62
	if !auth.VerifyPassword(r.FormValue("password"), a.AdminPassword) {
63
		web.RedirectWithError(w, r, "/admin/login", "Invalid password")
64
		return
65
	}
66
	token, err := a.Sessions.Create()
67
	if err != nil {
68
		a.Log.Error("create session failed", "err", err)
69
		web.RedirectWithError(w, r, "/admin/login", "Session error")
70
		return
71
	}
72
	a.Sessions.PruneExpired()
73
	http.SetCookie(w, a.Sessions.SessionCookie(token))
74
	http.Redirect(w, r, "/admin", http.StatusSeeOther)
75
}
76
77
func (a *App) logoutHandler(w http.ResponseWriter, r *http.Request) {
78
	if c, err := r.Cookie(a.Sessions.CookieName); err == nil && c.Value != "" {
79
		a.Sessions.Delete(c.Value)
80
	}
81
	http.SetCookie(w, a.Sessions.ClearCookie())
82
	http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
83
}
84
85
func (a *App) adminHandler(w http.ResponseWriter, r *http.Request) {
86
	total, _ := countQuotes(a.DB)
87
88
	query := r.URL.Query().Get("q")
89
	searched := strings.TrimSpace(query) != ""
90
91
	var found []Quote
92
	if searched {
93
		found, _ = searchQuotes(a.DB, query)
94
	} else {
95
		found, _ = listQuotes(a.DB, 50)
96
	}
97
	rows := make([]adminQuoteRow, 0, len(found))
98
	for _, q := range found {
99
		rows = append(rows, quoteToRow(q))
100
	}
101
102
	web.Render(a.Templates, w, "admin.html", adminPageData{
103
		Success:  r.URL.Query().Get("success"),
104
		Error:    r.URL.Query().Get("error"),
105
		Total:    total,
106
		Quotes:   rows,
107
		Query:    query,
108
		Searched: searched,
109
	}, a.Log)
110
}
111
112
func (a *App) adminAddQuote(w http.ResponseWriter, r *http.Request) {
113
	if err := r.ParseForm(); err != nil {
114
		web.RedirectWithError(w, r, "/admin", "Bad request")
115
		return
116
	}
117
	text := strings.TrimSpace(r.FormValue("text"))
118
	author := strings.TrimSpace(r.FormValue("author"))
119
	source := strings.TrimSpace(r.FormValue("source"))
120
	if text == "" || author == "" {
121
		web.RedirectWithError(w, r, "/admin", "Quote and author are required")
122
		return
123
	}
124
	if _, err := insertQuote(a.DB, text, author, source); err != nil {
125
		a.Log.Error("insert quote", "err", err)
126
		web.RedirectWithError(w, r, "/admin", "Failed to add quote")
127
		return
128
	}
129
	web.RedirectWithSuccess(w, r, "/admin", "Quote added")
130
}
131
132
func (a *App) adminDeleteQuote(w http.ResponseWriter, r *http.Request) {
133
	if err := deleteQuoteByShortID(a.DB, r.PathValue("short_id")); err != nil {
134
		a.Log.Error("delete quote", "err", err)
135
		web.RedirectWithError(w, r, "/admin", "Failed to remove quote")
136
		return
137
	}
138
	web.RedirectWithSuccess(w, r, "/admin", "Quote removed")
139
}