use templates, login/logout session support

This commit is contained in:
stryan 2020-09-17 16:19:05 -04:00
parent c3b934c974
commit e48d321f29
11 changed files with 160 additions and 26 deletions

View File

@ -12,15 +12,17 @@ type LdapConfig struct {
UserAttr string UserAttr string
UserOu string UserOu string
LdapDc string LdapDc string
LdapPass string
} }
type Config struct { type Config struct {
Ldap *LdapConfig Ldap *LdapConfig
Secret string Secret string
Tls bool TplPath string
Key string Tls bool
Cert string Key string
Port string Cert string
Port string
} }
func validateConfigEntry(entry string, name string) bool { func validateConfigEntry(entry string, name string) bool {
@ -51,11 +53,13 @@ func LoadConfig() (*Config, error) {
l.UserAttr = viper.GetString("userAttr") l.UserAttr = viper.GetString("userAttr")
l.UserOu = viper.GetString("userOu") l.UserOu = viper.GetString("userOu")
l.LdapDc = viper.GetString("ldapDc") l.LdapDc = viper.GetString("ldapDc")
l.LdapPass = viper.GetString("ldapPass")
c.Secret = viper.GetString("secret") c.Secret = viper.GetString("secret")
c.Tls = viper.GetBool("tls") c.Tls = viper.GetBool("tls")
c.Port = viper.GetString("port") c.Port = viper.GetString("port")
c.Key = viper.GetString("tls_key") c.Key = viper.GetString("tls_key")
c.Cert = viper.GetString("tls_cert") c.Cert = viper.GetString("tls_cert")
c.TplPath = viper.GetString("templates_path")
//Validate configs //Validate configs
if validateConfigEntry(l.Url, "ldapUrl") || validateConfigEntry(l.AdminUser, "adminUser") || validateConfigEntry(l.UserOu, "userOu") || validateConfigEntry(l.LdapDc, "ldapDc") || validateConfigEntry(l.UserAttr, "userAttr") { if validateConfigEntry(l.Url, "ldapUrl") || validateConfigEntry(l.AdminUser, "adminUser") || validateConfigEntry(l.UserOu, "userOu") || validateConfigEntry(l.LdapDc, "ldapDc") || validateConfigEntry(l.UserAttr, "userAttr") {

1
go.mod
View File

@ -4,6 +4,7 @@ go 1.14
require ( require (
github.com/go-ldap/ldap v3.0.3+incompatible github.com/go-ldap/ldap v3.0.3+incompatible
github.com/gorilla/securecookie v1.1.1
github.com/spf13/viper v1.7.1 github.com/spf13/viper v1.7.1
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
) )

2
go.sum
View File

@ -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/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 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 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/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-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= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=

View File

@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>Guildgate</h1>
<a href="/register">Register</a>
</body>
</html>

65
main.go
View File

@ -3,13 +3,26 @@ package main
import ( import (
"log" "log"
"net/http" "net/http"
"text/template"
"github.com/gorilla/securecookie"
) )
var Conf *Config 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) { func signupPage(res http.ResponseWriter, req *http.Request) {
if req.Method != "POST" { 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 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) { 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() { func main() {
Conf, _ = LoadConfig() Conf, _ = LoadConfig()
log.Println("Loaded config") log.Println("Loaded config")
http.HandleFunc("/register", signupPage) http.HandleFunc("/register", signupPage)
http.HandleFunc("/login", loginPage)
http.HandleFunc("/logout", logoutPage)
http.HandleFunc("/", homePage) 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) log.Printf("Guildgate starting on %v\n", Conf.Port)
var err error var err error
if Conf.Tls { if Conf.Tls {

37
session.go Normal file
View File

@ -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)
}

4
templates/footer.html Normal file
View File

@ -0,0 +1,4 @@
{{define "footer"}}
</body>
</html>
{{end}}

14
templates/header.html Normal file
View File

@ -0,0 +1,14 @@
{{ define "header" }}
<!DOCTYPE html>
<html lang="en">
<head>
<title>GuildGate</title>
</head>
<body>
<nav>
<li>Logged in as: {{.Username}}
<!-- <li><a href="/">Home</a></li>
<li><a href="/login">Login</a></li>
<li><a href="/logout">Logout</a></li>--!>
</nav>
{{end}}

7
templates/index.html Normal file
View File

@ -0,0 +1,7 @@
{{ define "index" }}
{{ template "header" .}}
<a href="/register">Register</a>
<a href="/login">Login</a>
<a href="/token">Get Token</a>
{{template "footer" .}}
{{ end }}

18
templates/login.html Normal file
View File

@ -0,0 +1,18 @@
{{ define "login" }}
{{ template "header" .}}
<h1> Login </h1>
<form action="/login" method="POST" novalidate>
<div>
<label>Username:</label>
<input type="text" name="username">
</div>
<div>
<label>Password:</label>
<input type="password" name="password">
</div>
<div>
<input type="submit" value="Login">
</div>
</form>
{{ template "footer" .}}
{{end}}

View File

@ -1,8 +1,5 @@
<!DOCTYPE html> {{ define "register" }}
<html> {{ template "header" .}}
<head>
<h1>Registration Form</h1>
</head>
<body> <body>
<form method="POST" action="/register"> <form method="POST" action="/register">
<table> <table>
@ -26,5 +23,5 @@
</tr> </tr>
</table> </table>
</form> </form>
</body> {{ template "footer" .}}
</html> {{ end }}