~evanj/cms

ref: 715dccc30b27b8e6bdd6330ff3d106e66f577087 cms/internal/c/c.go -rw-r--r-- 3.1 KiB
715dccc3Evan M Jones Fix(new*List): Remove error, remove panic when list is of size zero. 1 year, 6 months 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)
}