stuff
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Kekskurse 2021-11-25 01:32:48 +01:00
parent 508f7bf4b7
commit 360ee1c5fe
Signed by: kekskurse
GPG key ID: 728ACCB59341E7E4
12 changed files with 110 additions and 8 deletions

View file

@ -3,6 +3,7 @@ package main
import ( import (
"crypto/tls" "crypto/tls"
"embed" "embed"
"git.keks.cloud/kekskurse/go-sample-webpage/pkg/dashboard"
"git.keks.cloud/kekskurse/go-sample-webpage/pkg/sample" "git.keks.cloud/kekskurse/go-sample-webpage/pkg/sample"
"git.keks.cloud/kekskurse/go-sample-webpage/pkg/user" "git.keks.cloud/kekskurse/go-sample-webpage/pkg/user"
"git.keks.cloud/kekskurse/go-sample-webpage/pkg/webpage" "git.keks.cloud/kekskurse/go-sample-webpage/pkg/webpage"
@ -21,12 +22,13 @@ var webserver embed.FS
var migrationFS embed.FS var migrationFS embed.FS
func main() { func main() {
tokenAuth := jwtauth.New("HS256", []byte("secret"), nil)
config := webpage.WebPageConfig{ config := webpage.WebPageConfig{
Templates: webserver, Templates: webserver,
Static: webserver, Static: webserver,
Migrations: migrationFS, Migrations: migrationFS,
Token: tokenAuth,
Bootstrap: func(router chi.Router, template func(http.Handler) http.Handler) { Bootstrap: func(router chi.Router, template func(http.Handler) http.Handler) {
tokenAuth := jwtauth.New("HS256", []byte("secret"), nil)
db, err := sqlx.Open("mysql", "root:test@tcp(localhost:3306)/test?multiStatements=true") db, err := sqlx.Open("mysql", "root:test@tcp(localhost:3306)/test?multiStatements=true")
if err != nil { if err != nil {
panic(err) panic(err)
@ -40,6 +42,8 @@ func main() {
sample.Register(router) sample.Register(router)
user.Register(router, template, tokenAuth, uc, d, userconfig) user.Register(router, template, tokenAuth, uc, d, userconfig)
dashboard.Register(router, template)
}, },
} }

View file

@ -0,0 +1,32 @@
package dashboard
import (
"embed"
"github.com/go-chi/chi/v5"
"github.com/unrolled/render"
"net/http"
)
// content holds our static web server content.
//go:embed templates/*
var webserver embed.FS
var ren *render.Render
func Register(router chi.Router, template func(http.Handler) http.Handler) {
ren = render.New(render.Options{
//Layout: "layout",
FileSystem: &render.EmbedFileSystem{
FS: webserver,
},
})
router.Group(func(r chi.Router) {
r.Use(template)
r.Get("/dashboard", sampleCall)
})
}
func sampleCall(w http.ResponseWriter, r *http.Request) {
ren.HTML(w, http.StatusOK, "dashboard", map[string]string {"title": "World"})
}

View file

@ -25,5 +25,5 @@ func Register(router chi.Router) {
} }
func sampleCall(w http.ResponseWriter, r *http.Request) { func sampleCall(w http.ResponseWriter, r *http.Request) {
ren.HTML(w, http.StatusOK, "ssp", map[string]string {"title": "World"}) ren.HTML(w, http.StatusOK, "dashboard", map[string]string {"title": "World"})
} }

View file

@ -0,0 +1 @@
BLABLA <b>Something</b>

View file

@ -70,6 +70,7 @@ func Register(router chi.Router, template func(http.Handler) http.Handler, token
r.Get("/register", registerForm) r.Get("/register", registerForm)
r.Post("/register", register) r.Post("/register", register)
r.Get("/logout", logout) r.Get("/logout", logout)
r.Get("/validate/{mail}/{token}", validateMail)
}) })
router.Get("/captcha/{id}.png", captchaImage) router.Get("/captcha/{id}.png", captchaImage)
@ -95,6 +96,27 @@ func Register(router chi.Router, template func(http.Handler) http.Handler, token
} }
func validateMail(w http.ResponseWriter, r *http.Request) {
mailinput := chi.URLParam(r, "mail")
token := chi.URLParam(r, "token")
mailbytes, _ := base64.StdEncoding.DecodeString(mailinput)
mail := string(mailbytes)
res, err := uc.validateMail(mail, token)
if err != nil {
panic(err)
}
if res == false{
w.Write([]byte("Invalide or alrady used link"))
return
}
w.Write([]byte("Account is activated, you can login now"))
}
func captchaImage(w http.ResponseWriter, r *http.Request) { func captchaImage(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id") id := chi.URLParam(r, "id")
w.Header().Set("Content-Type", "image/png") w.Header().Set("Content-Type", "image/png")
@ -132,6 +154,7 @@ func login(w http.ResponseWriter, r *http.Request) {
expiration := time.Now().Add(365 * 24 * time.Hour) expiration := time.Now().Add(365 * 24 * time.Hour)
cookie := http.Cookie{Name: "jwt",Value:tokenstring,Expires:expiration} cookie := http.Cookie{Name: "jwt",Value:tokenstring,Expires:expiration}
http.SetCookie(w, &cookie) http.SetCookie(w, &cookie)
http.Redirect(w, r, "/dashboard", 301)
w.Write([]byte("Login ok")) w.Write([]byte("Login ok"))
} else { } else {
w.Write([]byte("Login failed")) w.Write([]byte("Login failed"))

View file

@ -14,6 +14,7 @@ type UserClient interface {
register(username, password, email string) (bool, error) register(username, password, email string) (bool, error)
login(username, password string, requiredMailValidation bool) (bool, error) login(username, password string, requiredMailValidation bool) (bool, error)
getMailValidationToken(email string, forceRecreate bool) (string, error) getMailValidationToken(email string, forceRecreate bool) (string, error)
validateMail(email, token string) (bool, error)
} }
type UserClientMemory struct { type UserClientMemory struct {
@ -26,6 +27,9 @@ func GetUserMemmoryClient() *UserClientMemory {
uc.users["admin"]="password" uc.users["admin"]="password"
return &uc return &uc
} }
func (uc *UserClientMemory) validateMail(email, token string) (bool, error) {
return true, nil
}
func (uc *UserClientMemory) register(username, password, email string) (bool, error) { func (uc *UserClientMemory) register(username, password, email string) (bool, error) {
if _, ok := uc.users[username]; ok { if _, ok := uc.users[username]; ok {
@ -130,6 +134,25 @@ func (uc UserClientSql) getMailValidationToken(email string, forceRecreate bool)
//token = fmt.Sprintf("%v/%v", base64.StdEncoding.EncodeToString([]byte(email)), token) //token = fmt.Sprintf("%v/%v", base64.StdEncoding.EncodeToString([]byte(email)), token)
return token, nil return token, nil
} }
func (uc *UserClientSql) validateMail(email, token string) (bool, error) {
user := User{}
err := uc.db.Get(&user, "SELECT * FROM `user` WHERE `mail` = ?", email)
if err != nil {
return false, err
}
if user.MailValidationCode != nil && *user.MailValidationCode == token {
_, err = uc.db.NamedExec("UPDATE `user` SET `mailValidationCode` = NULL, `mailValidate` = 1 WHERE id = :id LIMIT 1", map[string]interface{}{
"id": user.Id,
})
if err != nil {
return false, err
}
return true, nil
}
return false, nil
}
func (uc UserClientSql)hashAndSalt(pwd []byte) string { func (uc UserClientSql)hashAndSalt(pwd []byte) string {

View file

@ -2,6 +2,7 @@ package webpage
import ( import (
"bytes" "bytes"
"github.com/go-chi/jwtauth/v5"
"github.com/unrolled/render" "github.com/unrolled/render"
"html/template" "html/template"
"io" "io"
@ -41,6 +42,15 @@ func TemplateMiddelware(next http.Handler) http.Handler {
} }
rw.buf.Reset() rw.buf.Reset()
render.HTML(w, http.StatusOK, "sub", template.HTML(string(content)))
_, claims, _ := jwtauth.FromContext(r.Context())
loggedin := false
if claims["username"] != nil {
loggedin = true
}
render.HTML(w, http.StatusOK, "sub", map[string]interface{}{"loggedin": loggedin, "content": template.HTML(string(content))})
}) })
} }

View file

@ -5,6 +5,7 @@ import (
"embed" "embed"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware" "github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/jwtauth/v5"
"github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/mysql" "github.com/golang-migrate/migrate/v4/database/mysql"
"github.com/golang-migrate/migrate/v4/source/iofs" "github.com/golang-migrate/migrate/v4/source/iofs"
@ -20,6 +21,7 @@ type WebPageConfig struct {
Templates embed.FS Templates embed.FS
Static embed.FS Static embed.FS
Migrations embed.FS Migrations embed.FS
Token *jwtauth.JWTAuth
Bootstrap func(router chi.Router, middlewares func(http.Handler) http.Handler) Bootstrap func(router chi.Router, middlewares func(http.Handler) http.Handler)
} }
@ -67,6 +69,8 @@ func runWebpage() error {
}, },
}) })
r.Use(middleware.Logger) r.Use(middleware.Logger)
r.Use(jwtauth.Verifier(config.Token))
r.Handle("/static/*", http.FileServer(http.FS(config.Static))) r.Handle("/static/*", http.FileServer(http.FS(config.Static)))
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {

View file

@ -44,16 +44,23 @@
</li> </li>
</ul> </ul>
<ul class="navbar-nav me-auto"> <ul class="navbar-nav me-auto">
{{if .loggedin }}
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Account</a> <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Account</a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a class="dropdown-item" href="/login">Login</a>
<a class="dropdown-item" href="/register">Register</a>
<a class="dropdown-item" href="/me">Me</a> <a class="dropdown-item" href="/me">Me</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item" href="/logout">Logout</a> <a class="dropdown-item" href="/logout">Logout</a>
</div> </div>
</li> </li>
{{ else }}
<li class="nav-item">
<a class="nav-link" href="/register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</li>
{{ end }}
</ul> </ul>
</div> </div>

View file

@ -1 +1 @@
{{ . }} {{ .content }}

View file

@ -50,7 +50,6 @@ import (
"errors" "errors"
"io" "io"
"time" "time"
"fmt"
) )
const ( const (
@ -137,7 +136,6 @@ func Verify(id string, digits []byte) bool {
return false return false
} }
reald := globalStore.Get(id, true) reald := globalStore.Get(id, true)
fmt.Println(reald)
if reald == nil { if reald == nil {
return false return false
} }