better logout, switch to gorilla mux

This commit is contained in:
stryan 2020-09-22 14:37:54 -04:00
parent c3d1d097d8
commit 2e9ea4ddf5
6 changed files with 170 additions and 140 deletions

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.14
require ( require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-ldap/ldap v3.0.3+incompatible github.com/go-ldap/ldap v3.0.3+incompatible
github.com/gorilla/mux v1.8.0
github.com/gorilla/securecookie v1.1.1 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

@ -74,6 +74,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/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= 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/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=

150
main.go
View File

@ -5,6 +5,7 @@ import (
"net/http" "net/http"
"text/template" "text/template"
"github.com/gorilla/mux"
"github.com/gorilla/securecookie" "github.com/gorilla/securecookie"
) )
@ -14,146 +15,17 @@ var cookieHandler = securecookie.New(
securecookie.GenerateRandomKey(64), securecookie.GenerateRandomKey(64),
securecookie.GenerateRandomKey(32)) securecookie.GenerateRandomKey(32))
func signupPage(res http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
log.Println("GET /register")
u := getUserName(req)
if u != "" {
http.Redirect(res, req, "/", 302)
} else {
data := struct {
Title string
Username string
LoggedIn bool
}{
"Register",
"Unregistered",
false,
}
tpl.ExecuteTemplate(res, "register", data)
}
return
}
username := req.FormValue("username")
password := req.FormValue("password")
email := req.FormValue("email")
secret := req.FormValue("secret")
if Conf.Secret != "" && Conf.Secret != secret {
//Checking it as a token
err := validateToken(secret)
if err != nil {
log.Printf("Bad secret entered: %v\n", err)
res.Write([]byte("Get a load of this guy, not knowing the secret code"))
return
}
}
//insert into LDAP
log.Printf("Attempting to create account for %v", username)
err := createLDAPAccount(username, password, email)
if err == nil {
res.Write([]byte("User created!"))
return
} else {
res.Write([]byte("Failure to create account"))
return
}
}
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 {
data := struct {
Title string
Username string
LoggedIn bool
}{
"Login",
"Unregistered",
false,
}
tpl.ExecuteTemplate(res, "login", data)
}
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 tokenPage(res http.ResponseWriter, req *http.Request) {
u := getUserName(req)
if u == "" {
http.Redirect(res, req, "/", 302)
}
token, err := generateToken(u)
if err != nil {
log.Printf("Error generating token: %v", err)
tpl.ExecuteTemplate(res, "error", nil)
}
data := struct {
Title string
Username string
LoggedIn bool
Token string
}{
"Token Generation",
u,
true,
token,
}
tpl.ExecuteTemplate(res, "token", data)
}
func homePage(res http.ResponseWriter, req *http.Request) {
u := getUserName(req)
active := false
uname := "Unregistered"
if u != "" {
uname = u
active = true
}
data := struct {
Title string
Username string
LoggedIn bool
}{
"Index",
uname,
active,
}
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) router := mux.NewRouter().StrictSlash(true)
http.HandleFunc("/login", loginPage) router.HandleFunc("/", homePage).Methods("GET")
http.HandleFunc("/logout", logoutPage) router.HandleFunc("/register", signupPage).Methods("GET")
http.HandleFunc("/token", tokenPage) router.HandleFunc("/register", signup).Methods("POST")
http.HandleFunc("/", homePage) router.HandleFunc("/login", loginPage).Methods("GET")
router.HandleFunc("/login", login).Methods("POST")
router.HandleFunc("/logout", logoutPage).Methods("GET")
router.HandleFunc("/token", tokenPage).Methods("GET")
log.Printf("Registering templates from %v/\n", Conf.TplPath) log.Printf("Registering templates from %v/\n", Conf.TplPath)
tpl = template.Must(template.ParseGlob(Conf.TplPath + "/*.html")) 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)
@ -165,11 +37,11 @@ func main() {
} else if Conf.Key == "" { } else if Conf.Key == "" {
log.Fatalf("Need to specify a private key is usingTLS!\n") log.Fatalf("Need to specify a private key is usingTLS!\n")
} else { } else {
err = http.ListenAndServeTLS(":"+Conf.Port, Conf.Cert, Conf.Key, nil) err = http.ListenAndServeTLS(":"+Conf.Port, Conf.Cert, Conf.Key, router)
} }
} else { } else {
log.Printf("Starting unencrypted\n") log.Printf("Starting unencrypted\n")
err = http.ListenAndServe(":"+Conf.Port, nil) err = http.ListenAndServe(":"+Conf.Port, router)
} }
if err != nil { if err != nil {
log.Printf("HTTP server failed with %v\n", err) log.Printf("HTTP server failed with %v\n", err)

View File

@ -1,6 +1,9 @@
package main package main
import "net/http" import (
"log"
"net/http"
)
func setSession(uname string, res http.ResponseWriter) { func setSession(uname string, res http.ResponseWriter) {
value := map[string]string{ value := map[string]string{
@ -35,3 +38,50 @@ func clearSession(res http.ResponseWriter) {
} }
http.SetCookie(res, cookie) http.SetCookie(res, cookie)
} }
func signup(res http.ResponseWriter, req *http.Request) {
username := req.FormValue("username")
password := req.FormValue("password")
email := req.FormValue("email")
secret := req.FormValue("secret")
if Conf.Secret != "" && Conf.Secret != secret {
//Checking it as a token
err := validateToken(secret)
if err != nil {
log.Printf("Bad secret entered: %v\n", err)
res.Write([]byte("Get a load of this guy, not knowing the secret code"))
return
}
}
//insert into LDAP
log.Printf("Attempting to create account for %v", username)
err := createLDAPAccount(username, password, email)
if err == nil {
res.Write([]byte("User created!"))
return
} else {
res.Write([]byte("Failure to create account"))
return
}
}
func login(res http.ResponseWriter, req *http.Request) {
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 logout(res http.ResponseWriter, req *http.Request) {
clearSession(res)
}

8
templates/logout.html Normal file
View File

@ -0,0 +1,8 @@
{{ define "logout" }}
<html>
<h1>Logout</h1>
<p>You have succesfully logged out. You will be redirected to the index page momentarily</p>
<p><a href="/">Click here you aren't automatically redirected</a></p>
<meta http-equiv="Refresh" content="5; url='https://www.example.com'"/>
</html>
{{end}}

97
web.go Normal file
View File

@ -0,0 +1,97 @@
package main
import (
"log"
"net/http"
)
func signupPage(res http.ResponseWriter, req *http.Request) {
log.Println("GET /register")
u := getUserName(req)
if u != "" {
http.Redirect(res, req, "/", 302)
} else {
data := struct {
Title string
Username string
LoggedIn bool
}{
"Register",
"Unregistered",
false,
}
tpl.ExecuteTemplate(res, "register", data)
}
return
}
func loginPage(res http.ResponseWriter, req *http.Request) {
log.Println("GET /login")
u := getUserName(req)
if u != "" {
http.Redirect(res, req, "/", 302)
} else {
data := struct {
Title string
Username string
LoggedIn bool
}{
"Login",
"Unregistered",
false,
}
tpl.ExecuteTemplate(res, "login", data)
}
return
}
func logoutPage(res http.ResponseWriter, req *http.Request) {
logout(res, req)
tpl.ExecuteTemplate(res, "logout", nil)
return
}
func tokenPage(res http.ResponseWriter, req *http.Request) {
u := getUserName(req)
if u == "" {
http.Redirect(res, req, "/", 302)
}
token, err := generateToken(u)
if err != nil {
log.Printf("Error generating token: %v", err)
tpl.ExecuteTemplate(res, "error", nil)
}
data := struct {
Title string
Username string
LoggedIn bool
Token string
}{
"Token Generation",
u,
true,
token,
}
tpl.ExecuteTemplate(res, "token", data)
}
func homePage(res http.ResponseWriter, req *http.Request) {
u := getUserName(req)
active := false
uname := "Unregistered"
if u != "" {
uname = u
active = true
}
data := struct {
Title string
Username string
LoggedIn bool
}{
"Index",
uname,
active,
}
tpl.ExecuteTemplate(res, "index", data)
}