Debugging

This commit is contained in:
Jimmy 2022-03-13 07:06:39 +13:00
parent 8bc3cee328
commit dc8de8b4b9
31 changed files with 952 additions and 1040 deletions

73
app.go
View File

@ -2,56 +2,49 @@ package main
import ( import (
"fmt" "fmt"
"log"
"net/http"
c "git.1248.nz/1248/Otfe/controllers"
a "git.1248.nz/1248/Otfe/misc/auth"
"git.1248.nz/1248/Otfe/misc/helpers"
"github.com/husobee/vestigo"
) )
func main() { func main() {
fmt.Println("Starting") fmt.Println("Starting")
log.Fatal(http.ListenAndServe(":8080", router())) //log.Fatal(http.ListenAndServe(":8080", router()))
} }
func router() *vestigo.Router { // func router() *vestigo.Router {
router := vestigo.NewRouter() // router := vestigo.NewRouter()
var static c.Static // var static c.Static
router.Get("/", a.User(static.Home)) // router.Get("/", a.User(static.Home))
router.Get("/public/*", http.FileServer( // router.Get("/public/*", http.FileServer(
http.Dir(helpers.GetAssets())).ServeHTTP) // http.Dir(helpers.GetAssets())).ServeHTTP)
//User routes // //User routes
var user c.User // var user c.User
router.Get("/user", c.User{}.Index) // router.Get("/user", c.User{}.Index)
router.Get("/user/:username", a.Perm(user.Show, user.ShowSelf, // router.Get("/user/:username", a.Perm(user.Show, user.ShowSelf,
"user.show")) // "user.show"))
router.Get("/user/new", user.New) // router.Get("/user/new", user.New)
router.Post("/user/new", user.Create) // router.Post("/user/new", user.Create)
router.Get("/user/:username/edit", user.Edit) // router.Get("/user/:username/edit", user.Edit)
router.Post("/user/:username/edit", user.Update) // router.Post("/user/:username/edit", user.Update)
router.Post("/user/:username/delete", user.Delete) // router.Post("/user/:username/delete", user.Delete)
router.Get("/register", user.New) // router.Get("/register", user.New)
//Session routes // //Session routes
var session c.Session // var session c.Session
router.Get("/login", session.New) // router.Get("/login", session.New)
router.Post("/login", session.Create) // router.Post("/login", session.Create)
router.Post("/logout", session.Delete) // router.Post("/logout", session.Delete)
//Post routes // //Post routes
router.Get("/post", c.Post{}.Index) // router.Get("/post", c.Post{}.Index)
router.Get("/user/:id", c.Post{}.Show) // router.Get("/user/:id", c.Post{}.Show)
router.Get("/post/new", c.Post{}.New) // router.Get("/post/new", c.Post{}.New)
router.Post("/post/new", c.Post{}.Create) // router.Post("/post/new", c.Post{}.Create)
router.Get("/post/:id/edit", c.Post{}.Edit) // router.Get("/post/:id/edit", c.Post{}.Edit)
router.Post("/post/:id/edit", c.Post{}.Update) // router.Post("/post/:id/edit", c.Post{}.Update)
router.Post("/post/:id/delete", c.Post{}.Delete) // router.Post("/post/:id/delete", c.Post{}.Delete)
return router // return router
} // }

View File

@ -3,8 +3,8 @@ package main
import ( import (
"testing" "testing"
"git.1248.nz/1248/Otfe/misc/helpers" "git.technical.kiwi/go/otfe/misc/helpers"
"git.1248.nz/1248/Otfe/models" "git.technical.kiwi/go/otfe/models"
"github.com/globalsign/mgo/bson" "github.com/globalsign/mgo/bson"
) )

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.technical.kiwi/go/otfe
go 1.17

View File

@ -1,59 +1,59 @@
package auth // package auth
import ( // import (
"errors" // "errors"
"net/http" // "net/http"
"git.1248.nz/1248/Otfe/models" // "git.technical.kiwi/go/otfe/models"
) // )
type auth func(http.ResponseWriter, *http.Request, models.User) // type auth func(http.ResponseWriter, *http.Request, models.User)
func User(h auth) http.HandlerFunc { // func User(h auth) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { // return func(w http.ResponseWriter, r *http.Request) {
user, _ := getUserSession(r) // user, _ := getUserSession(r)
h(w, r, user) // h(w, r, user)
} // }
} // }
func Perm(handler auth, fallback auth, perm string) http.HandlerFunc { // func Perm(handler auth, fallback auth, perm string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { // return func(w http.ResponseWriter, r *http.Request) {
user, err := getUserSession(r) // user, err := getUserSession(r)
if err != nil { // if err != nil {
http.Redirect(w, r, "/login", http.StatusFound) // http.Redirect(w, r, "/login", http.StatusFound)
return // return
} // }
if user.HasPermission(perm) { // if user.HasPermission(perm) {
handler(w, r, user) // handler(w, r, user)
} else { // } else {
if fallback == nil { // if fallback == nil {
UnAuth(w) // UnAuth(w)
} else { // } else {
fallback(w, r, user) // fallback(w, r, user)
} // }
} // }
} // }
} // }
func getUserSession(r *http.Request) (models.User, error) { // func getUserSession(r *http.Request) (models.User, error) {
var session models.Session // var session models.Session
var user models.User // var user models.User
//Check for session in db // //Check for session in db
err := session.Get(r) // err := session.Get(r)
if err == nil { // if err == nil {
//Get user associated with the session // //Get user associated with the session
err = user.Read("_id", session.UserID) // err = user.Read("_id", session.UserID)
if err == nil { // if err == nil {
return user, nil // return user, nil
} // }
} // }
return user, errors.New("User not logged in") // return user, errors.New("User not logged in")
} // }
func UnAuth(w http.ResponseWriter) { // func UnAuth(w http.ResponseWriter) {
http.Error(w, "You are not authorized to view this page", // http.Error(w, "You are not authorized to view this page",
http.StatusForbidden) // http.StatusForbidden)
} // }

View File

@ -1,113 +1,113 @@
package auth // package auth
import ( // import (
"fmt" // "fmt"
"net/http" // "net/http"
"net/http/httptest" // "net/http/httptest"
"strings" // "strings"
"testing" // "testing"
"git.1248.nz/1248/Otfe/misc/helpers" // "git.technical.kiwi/go/otfe/misc/helpers"
"git.1248.nz/1248/Otfe/misc/helpers/cookie" // "git.technical.kiwi/go/otfe/misc/helpers/cookie"
"git.1248.nz/1248/Otfe/models" // "git.technical.kiwi/go/otfe/models"
"github.com/globalsign/mgo/bson" // "github.com/globalsign/mgo/bson"
) // )
func TestUser(t *testing.T) { // func TestUser(t *testing.T) {
//Setup user with session // //Setup user with session
recorder := httptest.NewRecorder() // recorder := httptest.NewRecorder()
user, session := userSession(t) // user, session := userSession(t)
request := request(t, session) // request := request(t, session)
u := User(handler) // u := User(handler)
//Run // //Run
u(recorder, request) // u(recorder, request)
//Check // //Check
body := recorder.Body.String() // body := recorder.Body.String()
if !strings.Contains(body, user.ID.Hex()) { // if !strings.Contains(body, user.ID.Hex()) {
t.Fail() // t.Fail()
} // }
//Setup without session // //Setup without session
recorder = httptest.NewRecorder() // recorder = httptest.NewRecorder()
request, _ = http.NewRequest("GET", "/", nil) // request, _ = http.NewRequest("GET", "/", nil)
//Run // //Run
u(recorder, request) // u(recorder, request)
//Check // //Check
helpers.Equals(t, recorder.Body.String(), // helpers.Equals(t, recorder.Body.String(),
"{ObjectIdHex(\"\") ObjectIdHex(\"\") []}") // "{ObjectIdHex(\"\") ObjectIdHex(\"\") []}")
} // }
func TestPerm(t *testing.T) { // func TestPerm(t *testing.T) {
p := Perm(handler, UnAuth, "perm") // p := Perm(handler, UnAuth, "perm")
recorder := httptest.NewRecorder() // recorder := httptest.NewRecorder()
user, session := userSession(t) // user, session := userSession(t)
request := request(t, session) // request := request(t, session)
p(recorder, request) // p(recorder, request)
if !strings.Contains(recorder.Body.String(), // if !strings.Contains(recorder.Body.String(),
"You are not authorized to view this page") { // "You are not authorized to view this page") {
t.Log("Authorization fail") // t.Log("Authorization fail")
t.Fail() // t.Fail()
} // }
p = Perm(handler, UnAuth, "test") // p = Perm(handler, UnAuth, "test")
recorder = httptest.NewRecorder() // recorder = httptest.NewRecorder()
p(recorder, request) // p(recorder, request)
if !strings.Contains(recorder.Body.String(), user.ID.Hex()) { // if !strings.Contains(recorder.Body.String(), user.ID.Hex()) {
t.Log("Has permission fail") // t.Log("Has permission fail")
t.Fail() // t.Fail()
} // }
recorder = httptest.NewRecorder() // recorder = httptest.NewRecorder()
request, err := http.NewRequest("GET", "/", nil) // request, err := http.NewRequest("GET", "/", nil)
helpers.Ok(t, err) // helpers.Ok(t, err)
p(recorder, request) // p(recorder, request)
if !strings.Contains(recorder.Body.String(), "login") { // if !strings.Contains(recorder.Body.String(), "login") {
t.Log("Login fail") // t.Log("Login fail")
t.Fail() // t.Fail()
} // }
} // }
func TestGetUserSession(t *testing.T) { // func TestGetUserSession(t *testing.T) {
user, session := userSession(t) // user, session := userSession(t)
request := request(t, session) // request := request(t, session)
//Test // //Test
user2, err := getUserSession(request) // user2, err := getUserSession(request)
helpers.Ok(t, err) // helpers.Ok(t, err)
helpers.Equals(t, user, user2) // helpers.Equals(t, user, user2)
} // }
func userSession(t *testing.T) (models.User, models.Session) { // func userSession(t *testing.T) (models.User, models.Session) {
models.DBWipeCollection("user", "session", "group") // models.DBWipeCollection("user", "session", "group")
group := models.NewGroup("test") // group := models.NewGroup("test")
group.ID = bson.NewObjectId() // group.ID = bson.NewObjectId()
group.Permissions["test"] = true // group.Permissions["test"] = true
//group.Admin = true // //group.Admin = true
helpers.Ok(t, group.Create()) // helpers.Ok(t, group.Create())
user := models.User{Name: "test", // user := models.User{Name: "test",
Email: "test"} // Email: "test"}
user.ID = bson.NewObjectId() // user.ID = bson.NewObjectId()
user.PrimaryGroup = group.ID // user.PrimaryGroup = group.ID
helpers.Ok(t, user.Create()) // helpers.Ok(t, user.Create())
session := models.Session{UserID: user.ID} // session := models.Session{UserID: user.ID}
session.ID = bson.NewObjectId() // session.ID = bson.NewObjectId()
helpers.Ok(t, session.Create()) // helpers.Ok(t, session.Create())
return user, session // return user, session
} // }
func request(t *testing.T, s models.Session) *http.Request { // func request(t *testing.T, s models.Session) *http.Request {
cookie := &http.Cookie{Name: "session", // cookie := &http.Cookie{Name: "session",
Value: cookie.Encode(s.ID.Hex())} // Value: cookie.Encode(s.ID.Hex())}
request, err := http.NewRequest("GET", "/", nil) // request, err := http.NewRequest("GET", "/", nil)
helpers.Ok(t, err) // helpers.Ok(t, err)
request.AddCookie(cookie) // request.AddCookie(cookie)
return request // return request
} // }
func handler(w http.ResponseWriter, r *http.Request, u models.User) { // func handler(w http.ResponseWriter, r *http.Request, u models.User) {
fmt.Fprint(w, u) // fmt.Fprint(w, u)
} // }

View File

@ -1,12 +1,12 @@
package b64 // package b64
import "encoding/base64" // import "encoding/base64"
func Encode(src string) string { // func Encode(src string) string {
return base64.URLEncoding.EncodeToString([]byte(src)) // return base64.URLEncoding.EncodeToString([]byte(src))
} // }
func Decode(src string) (string, error) { // func Decode(src string) (string, error) {
value, err := base64.URLEncoding.DecodeString(src) // value, err := base64.URLEncoding.DecodeString(src)
return string(value), err // return string(value), err
} // }

View File

@ -1,60 +1,60 @@
package config // package config
import ( // import (
"encoding/hex" // "encoding/hex"
"path/filepath" // "path/filepath"
"git.1248.nz/1248/Otfe/misc/helpers" // "git.technical.kiwi/go/otfe/misc/helpers"
"github.com/BurntSushi/toml" // "github.com/BurntSushi/toml"
) // )
//Configuration struct // //Configuration struct
type Configuration struct { // type Configuration struct {
DB database `toml:"database"` // DB database `toml:"database"`
Session session // Session session
} // }
// Database stuct // // Database stuct
type database struct { // type database struct {
Host string // Host string
Name string // Name string
User string // User string
Password string // Password string
} // }
type session struct { // type session struct {
SecretKey string // SecretKey string
Sessionkey string // Sessionkey string
Timeout int // Timeout int
} // }
var config *Configuration // var config *Configuration
func init() { // func init() {
Get() // Get()
} // }
// Get config info from toml config file // // Get config info from toml config file
func Get() *Configuration { // func Get() *Configuration {
if config == nil { // if config == nil {
_, err := toml.DecodeFile(getConfigFile(), &config) // _, err := toml.DecodeFile(getConfigFile(), &config)
helpers.CheckError(err) // helpers.CheckError(err)
} // }
return config // return config
} // }
func getConfigFile() string { // func getConfigFile() string {
return filepath.Join(helpers.GetRootDir(), "config.toml") // return filepath.Join(helpers.GetRootDir(), "config.toml")
} // }
func GetSecretKey() []byte { // func GetSecretKey() []byte {
config := Get() // config := Get()
key, err := hex.DecodeString(config.Session.SecretKey) // key, err := hex.DecodeString(config.Session.SecretKey)
helpers.CheckError(err) // helpers.CheckError(err)
return key // return key
} // }
func GetSessionKey() string { // func GetSessionKey() string {
return Get().Session.Sessionkey // return Get().Session.Sessionkey
} // }

View File

@ -1,7 +1,7 @@
package config // package config
import "testing" // import "testing"
func TestGetConfigFile(t *testing.T) { // func TestGetConfigFile(t *testing.T) {
t.Log(Get()) // t.Log(Get())
} // }

View File

@ -1,31 +0,0 @@
package cookie
import (
"errors"
"net/http"
"time"
"git.1248.nz/1248/Otfe/misc/b64"
)
func Create(w http.ResponseWriter, name string, value string) {
c := &http.Cookie{Name: name, Value: b64.Encode(value)}
http.SetCookie(w, c)
}
func Read(r *http.Request, name string) (string, error) {
c, err := r.Cookie(name)
if err != nil {
return "", errors.New("Cookie not found")
}
value, err := b64.Decode(c.Value)
if err != nil {
return "", errors.New("Failed to decode cookie")
}
return value, nil
}
func Delete(w http.ResponseWriter, name string) {
http.SetCookie(w, &http.Cookie{Name: name, MaxAge: -1, Expires: time.Unix(1, 0)})
}

View File

@ -1,39 +0,0 @@
package cookie
import (
"net/http"
"net/http/httptest"
"testing"
"git.1248.nz/1248/Otfe/misc/b64"
"git.1248.nz/1248/Otfe/misc/helpers"
)
func TestCreate(t *testing.T) {
recorder := httptest.NewRecorder()
Create(recorder, "test", "test")
request := &http.Request{Header: http.Header{
"Cookie": recorder.HeaderMap["Set-Cookie"]}}
cookie, err := request.Cookie("test")
if err != nil {
t.Fail()
return
}
value, err := b64.Decode(cookie.Value)
if err != nil || value != "test" {
t.Fail()
}
}
func TestRead(t *testing.T) {
cookie := &http.Cookie{Name: "test", Value: b64.Encode("test")}
request, err := http.NewRequest("GET", "", nil)
if err != nil {
t.Fail()
return
}
request.AddCookie(cookie)
value, err := Read(request, "test")
helpers.Equals(t, value, "test")
}

View File

@ -1,55 +1,55 @@
package helpers // package helpers
import ( // import (
"crypto/rand" // "crypto/rand"
"encoding/hex" // "encoding/hex"
"log" // "log"
"path/filepath" // "path/filepath"
"runtime" // "runtime"
"golang.org/x/crypto/bcrypt" // "golang.org/x/crypto/bcrypt"
) // )
//CheckError checks for errors and logs them and stops the program // //CheckError checks for errors and logs them and stops the program
func CheckError(err error) bool { // func CheckError(err error) bool {
if err != nil { // if err != nil {
log.Fatal(err) // log.Fatal(err)
return false // return false
} // }
return true // return true
} // }
func GetRootDir() string { // func GetRootDir() string {
_, b, _, _ := runtime.Caller(0) // _, b, _, _ := runtime.Caller(0)
dir := filepath.Dir(b) // dir := filepath.Dir(b)
return filepath.Dir(filepath.Dir(dir)) // return filepath.Dir(filepath.Dir(dir))
} // }
func GetAssets() string { // func GetAssets() string {
return GetRootDir() // return GetRootDir()
} // }
func HashPassword(password string) (string, error) { // func HashPassword(password string) (string, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(password), 14) // hash, err := bcrypt.GenerateFromPassword([]byte(password), 14)
return string(hash), err // return string(hash), err
} // }
func CheckPasswordHash(password, hash string) error { // func CheckPasswordHash(password, hash string) error {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) // err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err // return err
} // }
func RandHex() string { // func RandHex() string {
bytes := make([]byte, 12) // bytes := make([]byte, 12)
rand.Read(bytes) // rand.Read(bytes)
return hex.EncodeToString(bytes) // return hex.EncodeToString(bytes)
} // }
func Bytes(n int) ([]byte, error) { // func Bytes(n int) ([]byte, error) {
b := make([]byte, n) // b := make([]byte, n)
_, err := rand.Read(b) // _, err := rand.Read(b)
if err != nil { // if err != nil {
return nil, err // return nil, err
} // }
return b, nil // return b, nil
} // }

View File

@ -1,35 +1,35 @@
package helpers_test // package helpers_test
import ( // import (
"testing" // "testing"
"git.1248.nz/1248/Otfe/misc/helpers" // "git.technical.kiwi/go/otfe/misc/helpers"
"git.1248.nz/1248/Otfe/models" // "git.technical.kiwi/go/otfe/models"
) // )
func TestGetRootDir(t *testing.T) { // func TestGetRootDir(t *testing.T) {
t.Log("Root path:", helpers.GetRootDir()) // t.Log("Root path:", helpers.GetRootDir())
} // }
func TestHashPassword(t *testing.T) { // func TestHashPassword(t *testing.T) {
user := models.User{Email: "a@a.com", Username: "a"} // user := models.User{Email: "a@a.com", Username: "a"}
user.Delete("username", "a") // user.Delete("username", "a")
var err error // var err error
password := "43539jgifdkvnm4935078uJKJR**$ufjqd98438uiAHFJean89q34JKDFJ" // password := "43539jgifdkvnm4935078uJKJR**$ufjqd98438uiAHFJean89q34JKDFJ"
user.Password, err = helpers.HashPassword(password) // user.Password, err = helpers.HashPassword(password)
if err != nil { // if err != nil {
t.Fail() // t.Fail()
} // }
user.Create() // user.Create()
var user2 models.User // var user2 models.User
user2.Read("username", "a") // user2.Read("username", "a")
t.Log(helpers.CheckPasswordHash(password, user2.Password)) // t.Log(helpers.CheckPasswordHash(password, user2.Password))
} // }
func TestRandHex(t *testing.T) { // func TestRandHex(t *testing.T) {
for i := 0; i < 20; i++ { // for i := 0; i < 20; i++ {
t.Log(helpers.RandHex()) // t.Log(helpers.RandHex())
} // }
} // }

View File

@ -1,36 +1,36 @@
package helpers // package helpers
import ( // import (
"fmt" // "fmt"
"path/filepath" // "path/filepath"
"reflect" // "reflect"
"runtime" // "runtime"
"testing" // "testing"
) // )
// assert fails the test if the condition is false. // // assert fails the test if the condition is false.
func Assert(tb testing.TB, condition bool, msg string, v ...interface{}) { // func Assert(tb testing.TB, condition bool, msg string, v ...interface{}) {
if !condition { // if !condition {
_, file, line, _ := runtime.Caller(1) // _, file, line, _ := runtime.Caller(1)
fmt.Printf("\033[31m%s:%d: "+msg+"\033[39m\n\n", append([]interface{}{filepath.Base(file), line}, v...)...) // fmt.Printf("\033[31m%s:%d: "+msg+"\033[39m\n\n", append([]interface{}{filepath.Base(file), line}, v...)...)
tb.FailNow() // tb.FailNow()
} // }
} // }
// ok fails the test if an err is not nil. // // ok fails the test if an err is not nil.
func Ok(tb testing.TB, err error) { // func Ok(tb testing.TB, err error) {
if err != nil { // if err != nil {
_, file, line, _ := runtime.Caller(1) // _, file, line, _ := runtime.Caller(1)
fmt.Printf("\033[31m%s:%d: unexpected error: %s\033[39m\n\n", filepath.Base(file), line, err.Error()) // fmt.Printf("\033[31m%s:%d: unexpected error: %s\033[39m\n\n", filepath.Base(file), line, err.Error())
tb.FailNow() // tb.FailNow()
} // }
} // }
// equals fails the test if exp is not equal to act. // // equals fails the test if exp is not equal to act.
func Equals(tb testing.TB, exp, act interface{}) { // func Equals(tb testing.TB, exp, act interface{}) {
if !reflect.DeepEqual(exp, act) { // if !reflect.DeepEqual(exp, act) {
_, file, line, _ := runtime.Caller(1) // _, file, line, _ := runtime.Caller(1)
fmt.Printf("\033[31m%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\033[39m\n\n", filepath.Base(file), line, exp, act) // fmt.Printf("\033[31m%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\033[39m\n\n", filepath.Base(file), line, exp, act)
tb.FailNow() // tb.FailNow()
} // }
} // }

View File

@ -1,20 +1,20 @@
package rand // package rand
import ( // import (
"crypto/rand" // "crypto/rand"
"git.1248.nz/1248/Otfe/misc/b64" // "git.technical.kiwi/go/otfe/misc/b64"
) // )
//Bytes generates an random set of bytes n long // //Bytes generates an random set of bytes n long
func Bytes(n int) ([]byte, error) { // func Bytes(n int) ([]byte, error) {
b := make([]byte, n) // b := make([]byte, n)
_, err := rand.Read(b) // _, err := rand.Read(b)
return b, err // return b, err
} // }
//B64String generates a base 64 string n bytess long // //B64String generates a base 64 string n bytess long
func B64String(n int) (string, error) { // func B64String(n int) (string, error) {
b, err := Bytes(n) // b, err := Bytes(n)
return b64.Encode(string(b)), err // return b64.Encode(string(b)), err
} // }

View File

@ -1,41 +1,41 @@
package main // package main
import ( // import (
"git.1248.nz/1248/Otfe/misc/helpers" // "git.technical.kiwi/go/otfe/misc/helpers"
"git.1248.nz/1248/Otfe/models" // "git.technical.kiwi/go/otfe/models"
"github.com/globalsign/mgo/bson" // "github.com/globalsign/mgo/bson"
) // )
func main() { // func main() {
models.DBWipeCollection("group", "user", "session") // models.DBWipeCollection("group", "user", "session")
//admin user and group // //admin user and group
adminGroup := models.NewGroup("admin") // adminGroup := models.NewGroup("admin")
adminGroup.Admin = true // adminGroup.Admin = true
adminGroup.ID = bson.NewObjectId() // adminGroup.ID = bson.NewObjectId()
adminGroup.Permissions["user.show"] = true // adminGroup.Permissions["user.show"] = true
admin := models.User{} // admin := models.User{}
admin.Username = "admin" // admin.Username = "admin"
admin.Email = "admin" // admin.Email = "admin"
admin.ID = bson.NewObjectId() // admin.ID = bson.NewObjectId()
admin.Password, _ = helpers.HashPassword("admin") // admin.Password, _ = helpers.HashPassword("admin")
admin.PrimaryGroup = adminGroup.ID // admin.PrimaryGroup = adminGroup.ID
adminGroup.Users = append(adminGroup.Users, admin.ID) // adminGroup.Users = append(adminGroup.Users, admin.ID)
adminGroup.Create() // adminGroup.Create()
admin.Create() // admin.Create()
//user and user group // //user and user group
userGroup := models.NewGroup("user") // userGroup := models.NewGroup("user")
userGroup.ID = bson.NewObjectId() // userGroup.ID = bson.NewObjectId()
userGroup.Admin = false // userGroup.Admin = false
user := models.User{} // user := models.User{}
user.ID = bson.NewObjectId() // user.ID = bson.NewObjectId()
user.Username = "user" // user.Username = "user"
user.Email = "u" // user.Email = "u"
user.Password, _ = helpers.HashPassword("user") // user.Password, _ = helpers.HashPassword("user")
user.PrimaryGroup = userGroup.ID // user.PrimaryGroup = userGroup.ID
userGroup.Users = append(userGroup.Users, user.ID) // userGroup.Users = append(userGroup.Users, user.ID)
user.Create() // user.Create()
userGroup.Create() // userGroup.Create()
} // }

View File

@ -1,50 +1,50 @@
package models // package models
import ( // import (
"github.com/jinzhu/gorm" // "github.com/jinzhu/gorm"
) // )
//Group type // //Group type
type Group struct { // type Group struct {
gorm.Model // gorm.Model
Name string // Name string
Permissions map[string]bool // Permissions map[string]bool
Admin bool // Admin bool
Users []string // Users []string
} // }
func NewGroup(Name string) Group { // func NewGroup(Name string) Group {
var group Group // var group Group
group.Permissions = make(map[string]bool) // group.Permissions = make(map[string]bool)
return group // return group
} // }
//Create group // //Create group
func (g *Group) Create() error { // func (g *Group) Create() error {
return create(&g) // return create(&g)
} // }
//Read group // //Read group
func (g *Group) Read() error { // func (g *Group) Read() error {
return read(&g) // return read(&g)
} // }
//ReadAll groups // //ReadAll groups
func (g *Group) ReadAll() ([]Group, error) { // func (g *Group) ReadAll() ([]Group, error) {
var groups []Group // var groups []Group
var err error // var err error
err = readAll(&groups) // err = readAll(&groups)
return groups, err // return groups, err
} // }
//Update group // //Update group
func (g *Group) Update() error { // func (g *Group) Update() error {
return update(&g) // return update(&g)
} // }
//Delete group // //Delete group
func (g *Group) Delete() error { // func (g *Group) Delete() error {
err := delete(&g) // err := delete(&g)
return err // return err
} // }

View File

@ -1,25 +1,25 @@
package models // package models
import ( // import (
"testing" // "testing"
"github.com/globalsign/mgo/bson" // "github.com/globalsign/mgo/bson"
) // )
func TestCreateGroup(t *testing.T) { // func TestCreateGroup(t *testing.T) {
group := NewGroup("test") // group := NewGroup("test")
group.Users = append(group.Users, bson.NewObjectId()) // group.Users = append(group.Users, bson.NewObjectId())
group.Permissions["test"] = true // group.Permissions["test"] = true
t.Log(group.Create()) // t.Log(group.Create())
} // }
func TestReadGroup(t *testing.T) { // func TestReadGroup(t *testing.T) {
var group Group // var group Group
group.Read("name", "test") // group.Read("name", "test")
t.Log(group) // t.Log(group)
} // }
func TestReadAllGroup(t *testing.T) { // func TestReadAllGroup(t *testing.T) {
var group Group // var group Group
t.Log(group.ReadAll()) // t.Log(group.ReadAll())
} // }

View File

@ -1,33 +1,27 @@
package models package models
import ( import (
"fmt"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres" // _ "github.com/jinzhu/gorm/dialects/postgres"
"gorm.io/driver/sqlite"
) )
const ( // var (
host = "localhost" // gormdb, err =
port = 5432 // store = gormstore.New(gormdb, []byte("secret"))
user = "test" // )
password = "test"
dbname = "test"
)
var psqlInfo string var psqlInfo string
var db *gorm.DB var db *gorm.DB
func init() { func init() {
psqlInfo = fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
DB() DB()
} }
func DB() (*gorm.DB, error) { func DB() (*gorm.DB, error) {
if db == nil { if db == nil {
db, err := gorm.Open("postgres", psqlInfo) db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.LogMode(true) db.LogMode(true)
return db, err return db, err
} }

View File

@ -1,37 +1,42 @@
package models package models_test
import ( import (
"testing" "testing"
"git.technical.kiwi/go/otfe/models"
) )
func TestGetSession(t *testing.T) { func TestGetDB(t *testing.T) {
GetMongoSession() db, err := models.DB()
if !err || !db {
t.Fail()
}
} }
func TestGetCollection(t *testing.T) { func TestGetCollection(t *testing.T) {
GetCollection("test") //GetCollection("test")
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
create("user", &User{Name: "Ale"}) //create("user", &User{Name: "Ale"})
} }
func TestReadAll(t *testing.T) { func TestReadAll(t *testing.T) {
var u []User //var u []User
readAll("user", "", nil, &u) //readAll("user", "", nil, &u)
t.Log(u) //t.Log(u)
} }
func TestRead(t *testing.T) { func TestRead(t *testing.T) {
var u User //var u User
read("user", "name", "Ann", &u) //read("user", "name", "Ann", &u)
t.Log(u) //t.Log(u)
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
update("test", "name", "Ale", &User{Name: "Bob", Email: "z"}) //update("test", "name", "Ale", &User{Name: "Bob", Email: "z"})
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
t.Log(delete("user", "name", "Ann")) //t.Log(delete("user", "name", "Ann"))
} }

View File

@ -1,33 +1,33 @@
package models // package models
import ( // import (
"time" // "time"
"github.com/jinzhu/gorm" // "github.com/jinzhu/gorm"
) // )
//Post model // //Post model
type Post struct { // type Post struct {
gorm.Model // gorm.Model
Title string // Title string
Author string // Author string
Published time.Time // Published time.Time
LastEdited time.Time // LastEdited time.Time
Content []byte // Content []byte
} // }
//Create new post // //Create new post
func (p Post) Create() error { // func (p Post) Create() error {
return create(&p) // return create(&p)
} // }
func (p *Post) Read() (*Post, error) { // func (p *Post) Read() (*Post, error) {
err := read(&p) // err := read(&p)
return p, err // return p, err
} // }
func (p Post) ReadAll() ([]Post, error) { // func (p Post) ReadAll() ([]Post, error) {
var posts []Post // var posts []Post
err := readAll(&posts) // err := readAll(&posts)
return posts, err // return posts, err
} // }

View File

@ -4,7 +4,7 @@ import (
"net/http" "net/http"
"time" "time"
"git.1248.nz/1248/Otfe/misc/cookie" "git.technical.kiwi/go/otfe/misc/cookie"
"github.com/globalsign/mgo/bson" "github.com/globalsign/mgo/bson"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
) )

View File

@ -1,51 +1,51 @@
package models // package models
import ( // import (
"net/http" // "net/http"
"testing" // "testing"
"git.1248.nz/1248/Otfe/misc/b64" // "git.technical.kiwi/go/otfe/misc/b64"
"git.1248.nz/1248/Otfe/misc/helpers" // "git.technical.kiwi/go/otfe/misc/helpers"
"git.1248.nz/1248/Otfe/misc/rand" // "git.technical.kiwi/go/otfe/misc/rand"
) // )
func TestSessionCreate(t *testing.T) { // func TestSessionCreate(t *testing.T) {
var s1, s2 Session // var s1, s2 Session
s1.ID, _ = rand.B64String(32) // s1.ID, _ = rand.B64String(32)
if s1.Create() != nil { // if s1.Create() != nil {
t.Fail() // t.Fail()
} // }
read("session", "_id", s1.ID, &s2) // read("session", "_id", s1.ID, &s2)
if s1.ID != s2.ID { // if s1.ID != s2.ID {
t.Fail() // t.Fail()
} // }
} // }
func TestSessionRead(t *testing.T) { // func TestSessionRead(t *testing.T) {
var s1, s2 Session // var s1, s2 Session
s1.ID, _ = rand.B64String(32) // s1.ID, _ = rand.B64String(32)
if create("session", &s1) != nil { // if create("session", &s1) != nil {
t.Fatal("Failed to create session") // t.Fatal("Failed to create session")
} // }
if s2.Read(s1.ID) != nil { // if s2.Read(s1.ID) != nil {
t.Fatal("Failed to read session") // t.Fatal("Failed to read session")
} // }
if s1.ID != s2.ID { // if s1.ID != s2.ID {
t.Fatal("Ids don't match") // t.Fatal("Ids don't match")
} // }
} // }
func TestGet(t *testing.T) { // func TestGet(t *testing.T) {
DBWipeCollection("session") // DBWipeCollection("session")
var s1, s2 Session // var s1, s2 Session
s1.ID, _ = rand.B64String(32) // s1.ID, _ = rand.B64String(32)
s1.Create() // s1.Create()
c := &http.Cookie{Name: "session", // c := &http.Cookie{Name: "session",
Value: b64.Encode(s1.ID)} // Value: b64.Encode(s1.ID)}
request, err := http.NewRequest("GET", "/", nil) // request, err := http.NewRequest("GET", "/", nil)
helpers.Ok(t, err) // helpers.Ok(t, err)
request.AddCookie(c) // request.AddCookie(c)
s2.Get(request) // s2.Get(request)
helpers.Equals(t, s1, s2) // helpers.Equals(t, s1, s2)
} // }

View File

@ -1,80 +1,80 @@
package models // package models
import ( // import (
"errors" // "errors"
"fmt" // "fmt"
"github.com/globalsign/mgo/bson" // "github.com/globalsign/mgo/bson"
) // )
//User model // //User model
type User struct { // type User struct {
ID bson.ObjectId `bson:"_id,omitempty"` // ID bson.ObjectId `bson:"_id,omitempty"`
Email string `bson:"email"` // Email string `bson:"email"`
Name string `bson:"name"` // Name string `bson:"name"`
Username string `bson:"username"` // Username string `bson:"username"`
Password string `bson:"password"` // Password string `bson:"password"`
PrimaryGroup bson.ObjectId `bson:"primarygroup,omitempty"` // PrimaryGroup bson.ObjectId `bson:"primarygroup,omitempty"`
Groups []bson.ObjectId `bson:"groups,omitempty"` // Groups []bson.ObjectId `bson:"groups,omitempty"`
Session string // Session string
} // }
//Create user // //Create user
func (u *User) Create() error { // func (u *User) Create() error {
var user User // var user User
read("user", "email", u.Email, &user) // read("user", "email", u.Email, &user)
if u.Email == user.Email { // if u.Email == user.Email {
return errors.New("Email all ready used") // return errors.New("Email all ready used")
} // }
return create("user", &u) // return create("user", &u)
} // }
//Read user // //Read user
func (u *User) Read(key string, value interface{}) error { // func (u *User) Read(key string, value interface{}) error {
err := read("user", key, value, &u) // err := read("user", key, value, &u)
if err != nil { // if err != nil {
return errors.New("User doesn't exist") // return errors.New("User doesn't exist")
} // }
return nil // return nil
} // }
//ReadAll users // //ReadAll users
func (u *User) ReadAll() ([]User, error) { // func (u *User) ReadAll() ([]User, error) {
var users []User // var users []User
var err error // var err error
err = readAll("user", "", nil, &users) // err = readAll("user", "", nil, &users)
return users, err // return users, err
} // }
//Update user // //Update user
func (u *User) Update() error { // func (u *User) Update() error {
return update("user", "_id", u.ID, &u) // return update("user", "_id", u.ID, &u)
} // }
//Delete user // //Delete user
func (u *User) Delete(key string, value string) error { // func (u *User) Delete(key string, value string) error {
err := delete("user", key, value) // err := delete("user", key, value)
return err // return err
} // }
//HasPermission check if a given user is admin or has a given permisssion // //HasPermission check if a given user is admin or has a given permisssion
func (u *User) HasPermission(perm string) bool { // func (u *User) HasPermission(perm string) bool {
var group Group // var group Group
//Check primary group // //Check primary group
err := group.Read("_id", u.PrimaryGroup) // err := group.Read("_id", u.PrimaryGroup)
fmt.Println(group.Admin) // fmt.Println(group.Admin)
if err == nil && (group.Admin == true || group.Permissions[perm] == true) { // if err == nil && (group.Admin == true || group.Permissions[perm] == true) {
return true // return true
} // }
//Check other groups // //Check other groups
for id := range u.Groups { // for id := range u.Groups {
err = group.Read("_id", id) // err = group.Read("_id", id)
if err == nil && (group.Admin || group.Permissions[perm]) { // if err == nil && (group.Admin || group.Permissions[perm]) {
return true // return true
} // }
} // }
return false // return false
} // }

View File

@ -1,14 +0,0 @@
root: ./
tmp_path: ./tmp
build_name: runner-build
build_log: runner-build-errors.log
valid_ext: .go, .tpl, .tmpl, .html, .ccs, .js, .toml
no_rebuild_ext: .tpl, .tmpl, .html
ignored: assets, tmp
build_delay: 600
colors: 1
log_color_main: cyan
log_color_build: yellow
log_color_runner: green
log_color_watcher: magenta
log_color_app:

1
tmp/build-errors.log Normal file
View File

@ -0,0 +1 @@
exit status 1exit status 1