flounder

A simple gemini site builder
Log | Files | Refs | README | LICENSE

commit 24ee6c88b1078bc97712ad3c686c455ba152b717
parent f7d80c2a661b1b8f7717b743082d263952667591
Author: alex wennerberg <alex@alexwennerberg.com>
Date:   Sat, 24 Oct 2020 14:10:56 -0700

Add basic session handling

Diffstat:
Mconfig.go | 1+
Mflounder.toml | 2++
Mgo.mod | 1+
Mgo.sum | 4++++
Mhttp.go | 42+++++++++++++++++++++++++++++++++++++-----
Mmain.go | 3++-
6 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/config.go b/config.go @@ -13,6 +13,7 @@ type Config struct { SecretKey string DBFile string PasswdFile string // TODO remove + CookieStoreKey string OkExtensions []string MaxFileSize int } diff --git a/flounder.toml b/flounder.toml @@ -2,6 +2,8 @@ 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" diff --git a/go.mod b/go.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 diff --git a/go.sum b/go.sum @@ -6,6 +6,10 @@ github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8S 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= diff --git a/http.go b/http.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 @@ import ( var t *template.Template var DB *sql.DB +var SessionStore *sessions.CookieStore const InternalServerErrorMsg = "500: Internal Server Error" @@ -68,7 +70,12 @@ func rootHandler(w http.ResponseWriter, r *http.Request) { } 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 editFileHandler(w http.ResponseWriter, r *http.Request) { 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 @@ func uploadFilesHandler(w http.ResponseWriter, r *http.Request) { } 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 @@ func deleteFileHandler(w http.ResponseWriter, r *http.Request) { } 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 @@ func loginHandler(w http.ResponseWriter, r *http.Request) { _ = 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 { @@ -214,6 +238,13 @@ func loginHandler(w http.ResponseWriter, r *http.Request) { } } +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" func isOkUsername(s string) bool { @@ -320,6 +351,7 @@ func runHTTPServer() { 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) diff --git a/main.go b/main.go @@ -4,6 +4,7 @@ import ( "database/sql" "flag" "fmt" + "github.com/gorilla/sessions" "io/ioutil" "log" "os" @@ -110,7 +111,7 @@ func main() { 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)