all repos — flounder @ 24ee6c88b1078bc97712ad3c686c455ba152b717

A small site builder for the Gemini protocol

Add basic session handling
alex wennerberg alex@alexwennerberg.com
Sat, 24 Oct 2020 14:10:56 -0700
commit

24ee6c88b1078bc97712ad3c686c455ba152b717

parent

f7d80c2a661b1b8f7717b743082d263952667591

6 files changed, 47 insertions(+), 6 deletions(-)

jump to
M config.goconfig.go

@@ -13,6 +13,7 @@ Debug bool

SecretKey string DBFile string PasswdFile string // TODO remove + CookieStoreKey string OkExtensions []string MaxFileSize int }
M flounder.tomlflounder.toml

@@ -2,6 +2,8 @@ # Used in HTML templates and titles

SiteTitle="🐟flounder" RootDomain="localhost" FilesDirectory="./files" +# Generate a secure key +CookieStoreKey="12345678123456781234567812345678" # handles templates and static files # everything in the static subfolder will be served at root TemplatesDirectory="./templates"
M go.modgo.mod

@@ -6,6 +6,7 @@ require (

git.sr.ht/~adnano/gmi v0.1.0-alpha.2 github.com/BurntSushi/toml v0.3.1 github.com/gorilla/handlers v1.5.1 + github.com/gorilla/sessions v1.2.1 github.com/mattn/go-sqlite3 v1.14.4 golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
M go.sumgo.sum

@@ -6,6 +6,10 @@ github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=

github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +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/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/mattn/go-sqlite3 v1.14.4 h1:4rQjbDxdu9fSgI/r3KN72G3c2goxknAqHHgPWWs8UlI= github.com/mattn/go-sqlite3 v1.14.4/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
M http.gohttp.go

@@ -4,6 +4,7 @@ import (

"database/sql" "git.sr.ht/~adnano/gmi" "github.com/gorilla/handlers" + "github.com/gorilla/sessions" _ "github.com/mattn/go-sqlite3" "golang.org/x/crypto/bcrypt" "html/template"

@@ -20,6 +21,7 @@ )

var t *template.Template var DB *sql.DB +var SessionStore *sessions.CookieStore const InternalServerErrorMsg = "500: Internal Server Error"

@@ -68,7 +70,12 @@ }

} func editFileHandler(w http.ResponseWriter, r *http.Request) { - authUser := "alex" + session, _ := SessionStore.Get(r, "cookie-session") + authUser, ok := session.Values["auth_user"].(string) + if !ok { + renderError(w, "Forbidden", 403) + return + } fileName := filepath.Clean(r.URL.Path[len("/edit/"):]) filePath := path.Join(c.FilesDirectory, authUser, fileName) if r.Method == "GET" {

@@ -119,7 +126,12 @@ }

func uploadFilesHandler(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { - authUser := "alex" + session, _ := SessionStore.Get(r, "cookie-session") + authUser, ok := session.Values["auth_user"].(string) + if !ok { + renderError(w, "Forbidden", 403) + return + } r.ParseMultipartForm(10 << 20) file, fileHeader, err := r.FormFile("file") fileName := filepath.Clean(fileHeader.Filename)

@@ -153,7 +165,12 @@ http.Redirect(w, r, "/my_site", 302)

} func deleteFileHandler(w http.ResponseWriter, r *http.Request) { - authUser := "alex" + session, _ := SessionStore.Get(r, "cookie-session") + authUser, ok := session.Values["auth_user"].(string) + if !ok { + renderError(w, "Forbidden", 403) + return + } fileName := filepath.Clean(r.URL.Path[len("/delete/"):]) filePath := path.Join(c.FilesDirectory, authUser, fileName) if r.Method == "POST" {

@@ -163,7 +180,12 @@ http.Redirect(w, r, "/my_site", 302)

} func mySiteHandler(w http.ResponseWriter, r *http.Request) { - authUser := "alex" + session, _ := SessionStore.Get(r, "cookie-session") + authUser, ok := session.Values["auth_user"].(string) + if !ok { + renderError(w, "Forbidden", 403) + return + } // check auth files, _ := getUserFiles(authUser) data := struct {

@@ -197,7 +219,9 @@ var db_password []byte

_ = row.Scan(&db_password) if bcrypt.CompareHashAndPassword(db_password, []byte(password)) == nil { log.Println("logged in") - // create session + session, _ := SessionStore.Get(r, "cookie-session") + session.Values["auth_user"] = name + session.Save(r, w) http.Redirect(w, r, "/", 302) } else { data := struct {

@@ -212,6 +236,13 @@ return

} } } +} + +func logoutHandler(w http.ResponseWriter, r *http.Request) { + session, _ := SessionStore.Get(r, "cookie-session") + session.Options.MaxAge = -1 + session.Save(r, w) + http.Redirect(w, r, "/", 302) } const ok = "-0123456789abcdefghijklmnopqrstuvwxyz"

@@ -320,6 +351,7 @@ serveMux.HandleFunc(c.RootDomain+"/my_site", mySiteHandler)

serveMux.HandleFunc(c.RootDomain+"/edit/", editFileHandler) serveMux.HandleFunc(c.RootDomain+"/upload", uploadFilesHandler) serveMux.HandleFunc(c.RootDomain+"/login", loginHandler) + serveMux.HandleFunc(c.RootDomain+"/logout", logoutHandler) serveMux.HandleFunc(c.RootDomain+"/register", registerHandler) serveMux.HandleFunc(c.RootDomain+"/delete/", deleteFileHandler)
M main.gomain.go

@@ -4,6 +4,7 @@ import (

"database/sql" "flag" "fmt" + "github.com/gorilla/sessions" "io/ioutil" "log" "os"

@@ -110,7 +111,7 @@ c, err = getConfig(*configPath)

if err != nil { log.Fatal(err) } - + SessionStore = sessions.NewCookieStore([]byte(c.CookieStoreKey)) DB, err = sql.Open("sqlite3", c.DBFile) if err != nil { log.Fatal(err)