~evanj/cms

ref: 68c151793784838764aea443c6fd85d640fa57b3 cms/internal/c/c.go -rw-r--r-- 3.1 KiB
68c15179Evan M Jones Fix(ref clear+modal scroll): Fixing css on nested modal scroll dismisal. 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package c

import (
	"bytes"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"strings"

	"git.sr.ht/~evanj/cms/internal/m/user"
)

type KeyCookie = string

var KeyUserLogin KeyCookie = "KeyUserLogin"

type Controller struct {
	log *log.Logger
	db  dber
}

type dber interface {
	UserGet(username, password string) (user.User, error)
	UserGetFromToken(token string) (user.User, error)
}

func New(log *log.Logger, db dber) *Controller {
	return &Controller{
		log,
		db,
	}
}

// TODO: You know why this is bad, change it.
func (c *Controller) GetCookieUser2(w http.ResponseWriter, r *http.Request) (user.User, error) {
	cookie, err := r.Cookie(KeyUserLogin)
	if err != nil {
		return nil, err
	}

	user, err := c.db.UserGetFromToken(cookie.Value)
	if err != nil {
		return nil, err
	}

	return user, nil
}

func (c *Controller) GetCookieUser(w http.ResponseWriter, r *http.Request) (user.User, error) {
	user, err := c.GetCookieUser2(w, r)
	if err != nil {
		// No user in cookie, lets check in basic auth.

		u, p, ok := r.BasicAuth()
		if !ok {
			return nil, fmt.Errorf("no user available")
		}

		user, err = c.db.UserGet(u, p)
		if err != nil {
			return nil, err
		}
	}

	return user, nil
}

func (c *Controller) SetCookieUser(w http.ResponseWriter, r *http.Request, user user.User) {
	var tok string
	if user != nil {
		tok = user.Token()
	}

	http.SetCookie(w, &http.Cookie{
		Name:     KeyUserLogin,
		Value:    tok,
		HttpOnly: true,
		MaxAge:   50000,
		Path:     "/",
	})
}

func (c *Controller) String(w http.ResponseWriter, r *http.Request, str string) {
	w.Header().Add("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)
	fmt.Fprintf(w, str)
}

func (c *Controller) Error(w http.ResponseWriter, r *http.Request, code int, str string) {
	w.Header().Add("Content-Type", "text/plain")
	w.WriteHeader(code)
	fmt.Fprintf(w, str)
}

// TODO: You know why this is bad, change it.
func (c *Controller) HTML(w http.ResponseWriter, r *http.Request, tmpl *template.Template, data interface{}) {
	// Check JSON wanted.
	if !strings.Contains(r.Header.Get("Accept"), "text/html") {
		c.JSON(w, r, data)
		return
	}

	buf := bytes.Buffer{}
	if err := tmpl.Execute(&buf, data); err != nil {
		c.log.Println(err)
		c.Error(w, r, http.StatusInternalServerError, "failed to build html response")
		return
	}

	switch r.Method {
	case "POST":
		w.Header().Add("Cache-Control", "no-cache, must-revalidate, max-age=0")
		break
	default:
		w.Header().Add("Cache-Control", "no-store, must-revalidate, max-age=0")
		break
	}

	w.Header().Add("Content-Type", "text/html")
	w.Header().Add("Pragma", "no-cache")
	w.Header().Add("Expires", "Sat, 26 Jul 1997 05:00:00 GMT")
	w.WriteHeader(http.StatusOK)
	io.Copy(w, &buf)
}

// TODO: You know why this is bad, change it.
func (c *Controller) JSON(w http.ResponseWriter, r *http.Request, data interface{}) {
	bytes, err := json.Marshal(data)
	if err != nil {
		c.log.Println(err)
		c.Error(w, r, http.StatusInternalServerError, "failed to build json response")
		return
	}

	w.Header().Add("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(bytes)
}