diff --git a/config.go b/config.go
index 0f62a74..1fb5591 100644
--- a/config.go
+++ b/config.go
@@ -12,15 +12,17 @@ type LdapConfig struct {
UserAttr string
UserOu string
LdapDc string
+ LdapPass string
}
type Config struct {
- Ldap *LdapConfig
- Secret string
- Tls bool
- Key string
- Cert string
- Port string
+ Ldap *LdapConfig
+ Secret string
+ TplPath string
+ Tls bool
+ Key string
+ Cert string
+ Port string
}
func validateConfigEntry(entry string, name string) bool {
@@ -51,11 +53,13 @@ func LoadConfig() (*Config, error) {
l.UserAttr = viper.GetString("userAttr")
l.UserOu = viper.GetString("userOu")
l.LdapDc = viper.GetString("ldapDc")
+ l.LdapPass = viper.GetString("ldapPass")
c.Secret = viper.GetString("secret")
c.Tls = viper.GetBool("tls")
c.Port = viper.GetString("port")
c.Key = viper.GetString("tls_key")
c.Cert = viper.GetString("tls_cert")
+ c.TplPath = viper.GetString("templates_path")
//Validate configs
if validateConfigEntry(l.Url, "ldapUrl") || validateConfigEntry(l.AdminUser, "adminUser") || validateConfigEntry(l.UserOu, "userOu") || validateConfigEntry(l.LdapDc, "ldapDc") || validateConfigEntry(l.UserAttr, "userAttr") {
diff --git a/go.mod b/go.mod
index ecd0d11..3b1722d 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.14
require (
github.com/go-ldap/ldap v3.0.3+incompatible
+ github.com/gorilla/securecookie v1.1.1
github.com/spf13/viper v1.7.1
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
)
diff --git a/go.sum b/go.sum
index 1a46d62..0a70455 100644
--- a/go.sum
+++ b/go.sum
@@ -73,6 +73,8 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
+github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
diff --git a/index.html b/index.html
deleted file mode 100644
index 258a501..0000000
--- a/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
- Guildgate
- Register
-
-
diff --git a/main.go b/main.go
index d3e11be..bfaf7c1 100644
--- a/main.go
+++ b/main.go
@@ -3,13 +3,26 @@ package main
import (
"log"
"net/http"
+ "text/template"
+
+ "github.com/gorilla/securecookie"
)
var Conf *Config
+var tpl *template.Template
+var cookieHandler = securecookie.New(
+ securecookie.GenerateRandomKey(64),
+ securecookie.GenerateRandomKey(32))
func signupPage(res http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
- http.ServeFile(res, req, "register.html")
+ log.Println("GET /register")
+ u := getUserName(req)
+ if u != "" {
+ http.Redirect(res, req, "/", 302)
+ } else {
+ tpl.ExecuteTemplate(res, "register", nil)
+ }
return
}
@@ -35,15 +48,63 @@ func signupPage(res http.ResponseWriter, req *http.Request) {
}
}
+func loginPage(res http.ResponseWriter, req *http.Request) {
+ if req.Method != "POST" {
+ log.Println("GET /login")
+ u := getUserName(req)
+ if u != "" {
+ http.Redirect(res, req, "/", 302)
+ } else {
+ tpl.ExecuteTemplate(res, "login", nil)
+ }
+ return
+ }
+ username := req.FormValue("username")
+ password := req.FormValue("password")
+ log.Printf("Attempting login for user %v\n", username)
+ err := loginLDAPAccount(username, password)
+ if err != nil {
+ log.Printf("Error logging in user %v: %v\n", username, err)
+ res.Write([]byte("Error logging in. Incorrect password?"))
+ return
+ } else {
+ setSession(username, res)
+ http.Redirect(res, req, "/", 302)
+ return
+ }
+}
+
+func logoutPage(res http.ResponseWriter, req *http.Request) {
+ clearSession(res)
+ http.Redirect(res, req, "/", 302)
+}
+
func homePage(res http.ResponseWriter, req *http.Request) {
- http.ServeFile(res, req, "index.html")
+ u := getUserName(req)
+ uname := "Unregistered"
+ if u != "" {
+ uname = u
+ }
+ data := struct {
+ Title string
+ Username string
+ }{
+ "Index",
+ uname,
+ }
+
+ tpl.ExecuteTemplate(res, "index", data)
}
func main() {
Conf, _ = LoadConfig()
log.Println("Loaded config")
http.HandleFunc("/register", signupPage)
+ http.HandleFunc("/login", loginPage)
+ http.HandleFunc("/logout", logoutPage)
http.HandleFunc("/", homePage)
+ log.Printf("Registering templates from %v/\n", Conf.TplPath)
+ tpl = template.Must(template.ParseGlob(Conf.TplPath + "/*.html"))
log.Printf("Guildgate starting on %v\n", Conf.Port)
var err error
if Conf.Tls {
diff --git a/session.go b/session.go
new file mode 100644
index 0000000..62d633a
--- /dev/null
+++ b/session.go
@@ -0,0 +1,37 @@
+package main
+
+import "net/http"
+
+func setSession(uname string, res http.ResponseWriter) {
+ value := map[string]string{
+ "name": uname,
+ }
+ if encoded, err := cookieHandler.Encode("session", value); err == nil {
+ cookie := &http.Cookie{
+ Name: "session",
+ Value: encoded,
+ Path: "/",
+ }
+ http.SetCookie(res, cookie)
+ }
+}
+
+func getUserName(req *http.Request) (uname string) {
+ if cookie, err := req.Cookie("session"); err == nil {
+ cookieValue := make(map[string]string)
+ if err = cookieHandler.Decode("session", cookie.Value, &cookieValue); err == nil {
+ uname = cookieValue["name"]
+ }
+ }
+ return uname
+}
+
+func clearSession(res http.ResponseWriter) {
+ cookie := &http.Cookie{
+ Name: "session",
+ Value: "",
+ Path: "/",
+ MaxAge: -1,
+ }
+ http.SetCookie(res, cookie)
+}
diff --git a/templates/footer.html b/templates/footer.html
new file mode 100644
index 0000000..c8f56d8
--- /dev/null
+++ b/templates/footer.html
@@ -0,0 +1,4 @@
+{{define "footer"}}
+