~evanj/cms

ref: 27de4d9c907e2258a828fbfcda8f22b910df0f63 cms/internal/c/user/user.go -rw-r--r-- 2.7 KiB
27de4d9cEvan M Jones Feat(spaces): Added the ability to copy an entire space. 1 year, 11 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
package user

import (
	"log"
	"net/http"
	"strconv"

	"git.sr.ht/~evanj/cms/internal/c"
	"git.sr.ht/~evanj/cms/internal/m/space"
	"git.sr.ht/~evanj/cms/internal/m/user"
	"git.sr.ht/~evanj/cms/internal/s/tmpl"
)

var (
	indexHTML = tmpl.MustParse("html/index.html")
)

type User struct {
	*c.Controller
	log           *log.Logger
	db            dber
	signupEnabled bool
}

type dber interface {
	UserNew(username, password, verifyPassword string) (user.User, error)
	UserGet(username, password string) (user.User, error)
	UserGetFromToken(token string) (user.User, error)
	SpacesPerUser(user user.User, page int) ([]space.Space, error)
}

func New(log *log.Logger, db dber, signupEnabled bool) *User {
	return &User{
		c.New(log, db),
		log,
		db,
		signupEnabled,
	}
}

func (l *User) logout(w http.ResponseWriter, r *http.Request) {
	l.SetCookieUser(w, r, nil)
	http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}

func (l *User) login(w http.ResponseWriter, r *http.Request) {
	username := r.FormValue("username")
	password := r.FormValue("password")

	user, err := l.db.UserGet(username, password)
	if err != nil {
		l.Error(w, r, http.StatusBadRequest, "incorrect user credentials")
		return
	}

	l.SetCookieUser(w, r, user)
	http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}

func (l *User) signup(w http.ResponseWriter, r *http.Request) {
	if !l.signupEnabled {
		l.Error(w, r, http.StatusForbidden, "signups are forbidden at this time")
		return
	}

	username := r.FormValue("username")
	password := r.FormValue("password")
	verify := r.FormValue("verify")

	user, err := l.db.UserNew(username, password, verify)
	if err != nil {
		l.log.Println(err)
		l.Error(w, r, http.StatusBadRequest, err.Error())
		return
	}

	l.SetCookieUser(w, r, user)
	http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
}

func (l *User) home(w http.ResponseWriter, r *http.Request) {
	user, err := l.GetCookieUser(w, r)
	if err != nil {
		l.HTML(w, r, indexHTML, map[string]interface{}{
			"User": user,
		})
		return

	}

	page, err := strconv.Atoi(r.URL.Query().Get("page"))
	if err != nil || page < 1 {
		page = 1
	}

	page-- // Show one to user but start counting at zero for us.

	spaces, err := l.db.SpacesPerUser(user, page)
	if err != nil {
		l.Error(w, r, http.StatusInternalServerError, "failed to find spaces for user")
		return
	}

	l.HTML(w, r, indexHTML, map[string]interface{}{
		"User":   user,
		"Spaces": spaces,
	})
}

func (l *User) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/":
		l.home(w, r)
		return
	case "/user/login":
		l.login(w, r)
		return
	case "/user/logout":
		l.logout(w, r)
		return
	case "/user/signup":
		l.signup(w, r)
		return
	}

	http.NotFound(w, r)
}