~evanj/cms

ref: 27de4d9c907e2258a828fbfcda8f22b910df0f63 cms/internal/c/c.go -rw-r--r-- 2.8 KiB
27de4d9cEvan M Jones Feat(spaces): Added the ability to copy an entire space. 1 year, 7 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
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.WriteHeader(http.StatusOK)
	w.Header().Add("Content-Type", "text/plain")
	fmt.Fprintf(w, str)
}

func (c *Controller) Error(w http.ResponseWriter, r *http.Request, code int, str string) {
	w.WriteHeader(code)
	w.Header().Add("Content-Type", "text/plain")
	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{}) {
	// HTML response.
	if strings.Contains(r.Header.Get("Accept"), "text/html") {
		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
		}

		w.WriteHeader(http.StatusOK)
		w.Header().Add("Content-Type", "text/html")
		io.Copy(w, &buf)
		return
	}

	c.JSON(w, r, data)
}

// 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.WriteHeader(http.StatusOK)
	w.Header().Add("Content-Type", "application/json")
	w.Write(bytes)
}