add token generation, validation

This commit is contained in:
stryan 2020-09-17 17:36:39 -04:00
parent 6fadf63c4f
commit 7ba061682c
6 changed files with 105 additions and 3 deletions

1
go.mod
View File

@ -3,6 +3,7 @@ module guildgate
go 1.14
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-ldap/ldap v3.0.3+incompatible
github.com/gorilla/securecookie v1.1.1
github.com/spf13/viper v1.7.1

1
go.sum
View File

@ -36,6 +36,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=

33
main.go
View File

@ -43,10 +43,14 @@ func signupPage(res http.ResponseWriter, req *http.Request) {
secret := req.FormValue("secret")
if Conf.Secret != "" && Conf.Secret != secret {
log.Printf("Bad secret entered\n")
//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)
@ -101,6 +105,32 @@ func logoutPage(res http.ResponseWriter, req *http.Request) {
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
ShowLogin bool
ShowLogout bool
Token string
}{
"Token Generation",
u,
false,
true,
token,
}
tpl.ExecuteTemplate(res, "token", data)
}
func homePage(res http.ResponseWriter, req *http.Request) {
u := getUserName(req)
uname := "Unregistered"
@ -128,6 +158,7 @@ func main() {
http.HandleFunc("/register", signupPage)
http.HandleFunc("/login", loginPage)
http.HandleFunc("/logout", logoutPage)
http.HandleFunc("/token", tokenPage)
http.HandleFunc("/", homePage)
log.Printf("Registering templates from %v/\n", Conf.TplPath)
tpl = template.Must(template.ParseGlob(Conf.TplPath + "/*.html"))

5
templates/error.html Normal file
View File

@ -0,0 +1,5 @@
{{ define "error" }}
{{ template "header" .}}
An error occured. Please let the admin know.
{{template "footer" .}}
{{ end }}

11
templates/token.html Normal file
View File

@ -0,0 +1,11 @@
{{ define "token" }}
{{ template "header" .}}
<p>The following token has been generated and can be used to register an account on this website.</p>
<p>It is valid for 24 hours.</p>
<p>To Use: Paste the following string into the "Secret" box during registration</p>
<textarea id="token_area" name="generated_token" rows="4" cols="50">
{{ .Token }}
</textarea>
{{template "footer" .}}
{{ end }}

53
token.go Normal file
View File

@ -0,0 +1,53 @@
package main
import (
"errors"
"log"
"time"
"github.com/dgrijalva/jwt-go"
)
type tokenClaim struct {
Sponsor string `json:"sponsor_username"`
jwt.StandardClaims
}
func generateToken(sponsor string) (string, error) {
claim := tokenClaim{
Sponsor: sponsor,
StandardClaims: jwt.StandardClaims{
ExpiresAt: time.Now().UTC().Unix() + 86400,
Issuer: "GuildGate",
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
signedToken, err := token.SignedString([]byte(Conf.Secret))
if err != nil {
return "", err
} else {
return signedToken, nil
}
}
func validateToken(tok string) error {
token, err := jwt.ParseWithClaims(
tok,
&tokenClaim{},
func(token *jwt.Token) (interface{}, error) {
return []byte(Conf.Secret), nil
},
)
if err != nil {
return err
}
claims, ok := token.Claims.(*tokenClaim)
if !ok {
return errors.New("Invalid token sponsor passed")
}
if claims.ExpiresAt < time.Now().UTC().Unix() {
return errors.New("Token has expired")
}
log.Printf("Valid token received; sponsored by %v\n", claims.Sponsor)
return nil
}