Inital commit

This commit is contained in:
2022-02-24 01:07:09 +13:00
commit 8bc3cee328
55 changed files with 2292 additions and 0 deletions

33
controllers/controller.go Normal file
View File

@@ -0,0 +1,33 @@
package controllers
import (
"html/template"
"net/http"
"git.1248.nz/1248/Otfe/misc/helpers"
"github.com/globalsign/mgo/bson"
)
/*type Controller interface {
Index(w http.ResponseWriter, r *http.Request)
Show(w http.ResponseWriter, r *http.Request)
New(w http.ResponseWriter, r *http.Request)
Create(w http.ResponseWriter, r *http.Request)
Edit(w http.ResponseWriter, r *http.Request)
Update(w http.ResponseWriter, r *http.Request)
Delete(w http.ResponseWriter, r *http.Request)
}*/
var funcMap = template.FuncMap{
"getId": func(id bson.ObjectId) string {
return "1"
},
}
func t(w http.ResponseWriter, data interface{}, layout string) {
views := helpers.GetRootDir() + "/views/"
tmpl := template.Must(template.New("layout").Funcs(funcMap).
ParseFiles(views+"/layouts/layout.gtpl", views+"/layouts/header.gtpl", views+"/layouts/footer.gtpl", views+"/layouts/nav.gtpl", views+layout))
tmpl.ExecuteTemplate(w, "layout", data)
}

66
controllers/post.go Normal file
View File

@@ -0,0 +1,66 @@
package controllers
import (
"fmt"
"net/http"
"git.1248.nz/1248/Otfe/misc/helpers"
"git.1248.nz/1248/Otfe/models"
"github.com/husobee/vestigo"
)
//User handlers
type Post struct {
Title string
}
//Index of posts
func (p Post) Index(w http.ResponseWriter, r *http.Request) {
p.Title = "Posts"
t(w, p, "/post/posts.gtpl")
}
//Show given user
func (p Post) Show(w http.ResponseWriter, r *http.Request) {
t(w, p, "/post/post.gtpl")
}
//New user form
func (p Post) New(w http.ResponseWriter, r *http.Request) {
t(w, p, "/post/new.gtpl")
}
//Create new a user
func (p Post) Create(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var user models.User
var err error
user.Username = r.Form.Get("username")
user.Email = r.Form.Get("email")
user.Password, err = helpers.HashPassword(r.Form.Get("password"))
helpers.CheckError(err)
user.Create()
http.Redirect(w, r, "/user/"+user.Username, http.StatusFound)
}
//Edit form
func (p Post) Edit(w http.ResponseWriter, r *http.Request) {
var data userData
data.User.Read("username", vestigo.Param(r, "username"))
}
//Update user
func (p Post) Update(w http.ResponseWriter, r *http.Request) {
}
//Delete user
func (p Post) Delete(w http.ResponseWriter, r *http.Request) {
fmt.Println("Deleting " + vestigo.Param(r, "username"))
var user models.User
user.Delete("username", vestigo.Param(r, "username"))
http.Redirect(w, r, "/user", http.StatusFound)
}

72
controllers/session.go Normal file
View File

@@ -0,0 +1,72 @@
package controllers
import (
"errors"
"net/http"
"git.1248.nz/1248/Otfe/misc/cookie"
"git.1248.nz/1248/Otfe/misc/helpers"
"git.1248.nz/1248/Otfe/misc/rand"
"git.1248.nz/1248/Otfe/models"
)
//Session controllers
type Session struct{}
type pageData struct {
Title string
Err string
User models.User
}
//New login form
func (s *Session) New(w http.ResponseWriter, r *http.Request) {
var err error
data := pageData{Title: "Login"}
data.Err, err = cookie.Read(r, "error")
if err == nil {
cookie.Delete(w, "error")
}
t(w, data, "/static/login.gtpl")
}
//Create a new session
func (s *Session) Create(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
//Get email and password and check they are not empty
email := r.Form.Get("email")
password := r.Form.Get("password")
//Check if user exists
var user models.User
//Check password is correct
if user.Read("email", email) == nil &&
helpers.CheckPasswordHash(password, user.Password) == nil {
id, _ := rand.B64String(32)
sess := models.Session{ID: id, UserID: user.ID}
sess.Create()
cookie.Create(w, "session", sess.ID)
http.Redirect(w, r, "/", http.StatusFound)
} else {
loginFail(w, r, errors.New("Email or password incorrect"))
}
}
//Delete session
func (s *Session) Delete(w http.ResponseWriter, r *http.Request) {
id, err := cookie.Read(r, "session")
//Check user is logged in
if err == nil {
cookie.Delete(w, "session")
var session models.Session
session.Delete(id)
http.Redirect(w, r, "/", http.StatusFound)
}
}
func loginFail(w http.ResponseWriter, r *http.Request, err error) {
cookie.Create(w, "error", err.Error())
http.Redirect(w, r, "/login", http.StatusFound)
}

102
controllers/session_test.go Normal file
View File

@@ -0,0 +1,102 @@
package controllers_test
import (
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"git.1248.nz/1248/Otfe/controllers"
"git.1248.nz/1248/Otfe/misc/b64"
"git.1248.nz/1248/Otfe/misc/helpers"
"git.1248.nz/1248/Otfe/models"
)
func TestSessionNew(t *testing.T) {
var s controllers.Session
handler := http.HandlerFunc(s.New)
req, err := http.NewRequest("GET", "/login", nil)
w := httptest.NewRecorder()
if err != nil {
t.Fatal(err)
}
handler(w, req)
body := w.Body.String()
if !strings.Contains(body, "<title>Login</title>") {
t.Fail()
}
}
func TestSessionCreate(t *testing.T) {
//Create test user
var s controllers.Session
handler := http.HandlerFunc(s.Create)
req, w := setup(t, "POST", "/login")
addTofForm(req, "email=test", "password=test")
handler(w, req)
errorMessage := getCookie("error", w.Header()["Set-Cookie"])
t.Log(errorMessage)
t.Log(b64.Decode(errorMessage))
header := w.Header()
sessionid := getCookie("session", header["Set-Cookie"])
var session models.Session
if session.Read(sessionid) != nil {
t.Fatal("Could not find session")
}
}
/*func testloginFail(t *testing.T) {
}*/
func setup(t *testing.T, method string, url string) (*http.Request, *httptest.ResponseRecorder) {
req, err := http.NewRequest("POST", "/login", nil)
w := httptest.NewRecorder()
if err != nil {
t.Fatal(err)
}
return req, w
}
func createUser(t *testing.T, email string, password string) models.User {
password, err := helpers.HashPassword(password)
if err != nil {
t.Fatal("Failed to create password")
}
user := models.User{Email: email, Password: password}
if user.Create() != nil {
t.Fatal("failed to create user")
}
return user
}
func getCookie(name string, cookies []string) string {
for _, cookie := range cookies {
a := strings.Split(cookie, "=")
if a[0] == name {
return a[1]
}
}
return "Cookie not found"
}
func addTofForm(r *http.Request, values ...string) {
form, _ := url.ParseQuery(r.URL.RawQuery)
for _, value := range values {
v := strings.Split(value, "=")
form.Add(v[0], v[1])
}
r.URL.RawQuery = form.Encode()
r.Form.Encode()
}

29
controllers/static.go Normal file
View File

@@ -0,0 +1,29 @@
package controllers
import (
"net/http"
"git.1248.nz/1248/Otfe/models"
)
//Static pages
type Static struct{}
type staticData struct {
Title string
User models.User
}
type contextKey string
func (c contextKey) String() string {
return string(c)
}
//Home page
func (s *Static) Home(w http.ResponseWriter, r *http.Request, u models.User) {
data := staticData{Title: "Otfe"}
data.User = u
//fmt.Fprintln(w, data.User)
t(w, data, "/static/home.gtpl")
}

91
controllers/user.go Normal file
View File

@@ -0,0 +1,91 @@
package controllers
import (
"fmt"
"net/http"
"git.1248.nz/1248/Otfe/misc/auth"
"git.1248.nz/1248/Otfe/misc/helpers"
"git.1248.nz/1248/Otfe/models"
"github.com/husobee/vestigo"
)
type userData struct {
Title string
Users []models.User
User models.User
}
//User handlers
type User struct{}
//Index list all users
func (u User) Index(w http.ResponseWriter, r *http.Request) {
var err error
data := userData{Title: "Users"}
data.Users, err = data.User.ReadAll()
helpers.CheckError(err)
t(w, data, "/user/users.gtpl")
}
//Show given user
func (u *User) Show(w http.ResponseWriter, r *http.Request, user models.User) {
var data userData
data.User.Read("username", vestigo.Param(r, "username"))
//matchUser(data.User, w, r)
data.Title = data.User.Username
t(w, data, "/user/user.gtpl")
}
//ShowSelf show given user if they are the same as the authenticated one
func (u *User) ShowSelf(w http.ResponseWriter, r *http.Request, user models.User) {
if user.Username != vestigo.Param(r, "username") {
auth.UnAuth(w)
return
}
var data userData
data.User = user
data.Title = data.User.Username
t(w, data, "/user/user.gtpl")
}
//New user form
func (u *User) New(w http.ResponseWriter, r *http.Request) {
data := userData{Title: "New User"}
t(w, data, "/user/new.gtpl")
}
//Create new a user
func (u *User) Create(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
var user models.User
var err error
user.Username = r.Form.Get("username")
user.Email = r.Form.Get("email")
user.Password, err = helpers.HashPassword(r.Form.Get("password"))
helpers.CheckError(err)
user.Create()
http.Redirect(w, r, "/user/"+user.Username, http.StatusFound)
}
//Edit form
func (u *User) Edit(w http.ResponseWriter, r *http.Request) {
var data userData
data.User.Read("username", vestigo.Param(r, "username"))
}
//Update user
func (u *User) Update(w http.ResponseWriter, r *http.Request) {
}
//Delete user
func (u *User) Delete(w http.ResponseWriter, r *http.Request) {
fmt.Println("Deleting " + vestigo.Param(r, "username"))
var user models.User
user.Delete("username", vestigo.Param(r, "username"))
http.Redirect(w, r, "/user", http.StatusFound)
}