about summary refs log tree commit diff
path: root/src/http.go
blob: 13276f728c251b8f8dc7826901fbed868225c472 (plain)
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
164
165
166
167
168
169
170
171
172
package main

import (
	"encoding/base64"
	"flag"
	"fmt"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/gorilla/mux"
)

var (
	port                 *int     // port the http server listens on
	usernames            []string // list of usernames
	currentVpnRemotePort *int
)

// Credentials stores user credentials
type Credentials struct {
	Username   string
	Accesscode string
	Hostname   string
}

func registerHTTPFlags() {
	port = flag.Int("port", 8081, "The port the http server should listen on")
	currentVpnRemotePort = flag.Int("initialVPNPort", 1194, "the initial vpn port")
}

func setupHTTPServer() http.Server {
	r := mux.NewRouter()

	r.HandleFunc("/", indexHandler)
	r.HandleFunc("/register", registerGetHandler).Methods("GET")
	r.HandleFunc("/register", registerPostHandler).Methods("POST")
	r.HandleFunc("/credentials", credentialsGetHandler).Methods("GET")

	return http.Server{
		Addr:    fmt.Sprintf("0.0.0.0:%d", *port),
		Handler: r,
	}
}

// Host of the index file
func indexHandler(w http.ResponseWriter, r *http.Request) {
	readFileToReponse(w, "/index.html")
}

// Read register page
func registerGetHandler(w http.ResponseWriter, r *http.Request) {
	readFileToReponse(w, "/register.html")
}

// Process a registration
func registerPostHandler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	username := r.Form.Get("username")

	// test if the username has already been chosen
	if !isUniq(username) {
		log.Println("redirecting to usernameTaken")
		usernameTakenGetHandler(w, r)
		return
	}

	if !isValid(username) {
		return
	}

	// add the new username to the list of usernames
	usernames = append(usernames, username)

	// generate a new accesscode
	accesscode := newAccessCode(16)
	log.Printf("Generated a new AccessCode for user \"%s\": \"%s\"", username, accesscode)

	// generate a new companion
	spawnCompanion(username, accesscode)

	log.Println("---")
	log.Println("Done generating the containers, filling the credentials page using a template")

	usernameBytes := []byte(username)
	usernameBase64 := base64.StdEncoding.EncodeToString(usernameBytes)

	accesscodeBytes := []byte(accesscode)
	accesscodeBase64 := base64.StdEncoding.EncodeToString(accesscodeBytes)

	// insert the username and the accesscode into the http request parameters
	r.Form["username"] = []string{usernameBase64}
	r.Form["accesscode"] = []string{accesscodeBase64}

	credentialsGetHandler(w, r)
}

func usernameTakenGetHandler(w http.ResponseWriter, r *http.Request) {
	log.Println("[usernameTaken]")
	readFileToReponse(w, "/usernameTaken.html")
}

func isUniq(username string) bool {
	for _, user := range usernames {
		if username == user {
			return false
		}
	}
	return true
}

func isValid(username string) bool {
	if username == "traefik" || username == "register" {
		return false
	}
	return true
}

func readFileToReponse(w http.ResponseWriter, path string) {
	requestedFile := strings.Replace(path, "..", "", -1)

	contents, readError := ioutil.ReadFile(fmt.Sprintf("hosted/%s", requestedFile))

	if readError != nil {
		w.Write([]byte(fmt.Sprintf("unable to read %s", requestedFile)))
	} else {
		w.Write([]byte(contents))
	}
}

func credentialsGetHandler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	usernameBase64 := r.Form.Get("username")
	username, err := base64.StdEncoding.DecodeString(usernameBase64)
	if err != nil {
		fmt.Println("error decoding username base64:", err)
	}

	accesscodeBase64 := r.Form.Get("accesscode")
	accesscode, err := base64.StdEncoding.DecodeString(accesscodeBase64)
	if err != nil {
		fmt.Println("error decoding accesscode base64:", err)
	}

	log.Println("[ ] Credentials GET Handler")
	log.Println("%#v", r.Form)
	log.Printf("username: %s", username)
	log.Printf("accesscode: %s", accesscode)

	// create a new template reading the credentials template file
	// the template then gets executed inserting the username and the accesscode
	log.Println("creating new template")
	t := template.New("")
	log.Println("parsing template file")
	t, err = t.ParseFiles("./hosted/credentials.html")
	if err != nil {
		log.Println(err)
	}
	log.Println("creating a credentials struct")
	creds := Credentials{
		Username:   string(username),
		Accesscode: string(accesscode),
		Hostname:   string(os.Getenv("HOSTNAME")),
	}
	log.Println("executing the template")
	t.ExecuteTemplate(w, "credentials", creds)
	log.Println("done executing the template")
}