forked from lukevers/kittens
/
main.go
163 lines (123 loc) · 5.46 KB
/
main.go
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package main
import (
"flag"
"github.com/gorilla/mux"
"html/template"
"net/http"
"strconv"
"sync"
)
var (
err error
wg sync.WaitGroup
users []*User
servers []*Server
)
var (
templates = template.Must(template.New("").Funcs(AddTemplateFunctions(nil)).ParseGlob("app/views/*"))
)
func main() {
// Parse flags
flag.Parse()
// Initialize database
InitDatabase()
// Remove old sessions
CleanSessions()
info("Starting webserver")
// Web server
r := mux.NewRouter()
// Handles GET requests for "/" which is our root page.
r.HandleFunc("/", HandleRoot)
// Handles GET requests to "/login" which displays a form that a user
// can use to try and login.
r.HandleFunc("/login", HandleLogin).Methods("GET")
// Handles POST requests for "/login" which tests if a user is
// logging in with correct details or not.
r.HandleFunc("/login", HandleLoginForm).Methods("POST")
// Handles GET requests to "/login/2fa" which displays a form that a
// user can use to try their 2fa token on.
r.HandleFunc("/login/2fa", HandleLogin2FA).Methods("GET")
// Handles POST requests to "/login/2fa" which tests if a users 2fa
// token is correct or not.
r.HandleFunc("/login/2fa", HandleLoginForm2FA).Methods("POST")
// Handle logout requests which removes the session and logs the user out
r.HandleFunc("/logout", HandleLogout)
// Handles GET requests for "/settings" which is a page where users
// can update their settings.
r.HandleFunc("/settings", HandleSettings).Methods("GET")
// Handles POST requests for "/settings" which is a page where users
// can update their settings. POSTing here will update settings.
r.HandleFunc("/settings", HandleUpdateSettings).Methods("POST")
// Handles GET requests for "/settings/2fa/generate" which is a page
// that generates a QR code for Two Factor Auth.
r.HandleFunc("/settings/2fa/generate", HandleGenerate2FA).Methods("GET")
// Handles POST requests for "/settings/2fa/verify" which checks to
// see if a 2FA token is correct. If it is, then we remove the temp
// secret key from the session and add it to the database.
r.HandleFunc("/settings/2fa/verify", HandleVerify2FA).Methods("POST")
// Handles POST requests for "/settings/2fa/disable" which disables
// 2FA for the users account.
r.HandleFunc("/settings/2fa/disable", HandleDisable2FA).Methods("POST")
// Handles GET requests for "/users" which is an admin-only page
r.HandleFunc("/users", HandleUsers).Methods("GET")
// Handles POST requests for "/users/new" which is a form where
// new users can be added.
r.HandleFunc("/users/new", HandleNewUser).Methods("POST")
// Handles POST requests for "/users/delete" which is how users
// can be deleted.
r.HandleFunc("/users/delete", HandleUserDelete).Methods("POST")
// Handles POST requests for "/users/admin" which is a form where
// administrators can promote/demote users.
r.HandleFunc("/users/admin", HandleUserAdminSwitch).Methods("POST")
// Handles GET requests for "/server/new" which is a page where a
// user can add a new server.
r.HandleFunc("/server/new", HandleNew).Methods("GET")
// Handles POST requests for "/server/new" which adds a new server
r.HandleFunc("/server/new", HandleAddNew).Methods("POST")
// Handles GET requests for "/server/{id}" which is a server page
r.HandleFunc("/server/{id}", HandleServer).Methods("GET")
// Handles POST requests for "/server/{id}" which is an endpoint where
// server information can be updated.
r.HandleFunc("/server/{id}", HandleUpdateServer).Methods("POST")
// Handles GET requests for "/server/{id}/channel/" which is a page
// that looks for a URL fragment at the end of the url. JavaScript
// then takes that URL fragment and URL encodes the fragment. After
// URL encoding the fragment we're redirected the correct channel page.
r.HandleFunc("/server/{id}/channel/", HandleChannelRedirect).Methods("GET")
// Handles GET requests for "/server/{id}/channel/{channel}" which
// is a page for a specific channel for a specific server.
r.HandleFunc("/server/{id}/channel/{channel}", HandleChannel).Methods("GET")
// Handles POST requests for "/server/{id}/enable" which takes a bool
// and enables--if it is disabled--the server if the bool is true, and
// disables--if it is enabled--the server if the bool is false.
r.HandleFunc("/server/{id}/enable", HandleEnableServer).Methods("POST")
// Handles POST requests for "/server/{id}/channel/join" which takes
// a specific channel and joins it.
r.HandleFunc("/server/{id}/channel/join", HandleJoinChannel).Methods("POST")
// Handles POST requests for "/server/{id}/channel/part" which takes
// a specific channel and parts it.
r.HandleFunc("/server/{id}/channel/part", HandlePartChannel).Methods("POST")
// Handle all other static files and folders (eg. CSS/JS).
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./public")))
// Get all users
db.Find(&users, &User{})
for _, user := range users {
// Get all of the servers for each user
db.Table("servers").Where("user_id = ?", user.Id).Find(&user.Servers)
// Create servers
for _, server := range user.Servers {
// Get all of the channels for each server
db.Table("channels").Where("server_id = ?", server.Id).Find(&server.Channels)
// Add to slice of server
servers = append(servers, server)
// Add to wait group
wg.Add(1)
// Start our goroutine
go server.Create()
}
}
http.Handle("/", r)
http.ListenAndServe(*interfaceFlag+":"+strconv.Itoa(*portFlag), nil)
infof("Webserver running on port %s", *portFlag)
wg.Wait()
}