Inital commit
This commit is contained in:
50
models/group.go
Normal file
50
models/group.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
//Group type
|
||||
type Group struct {
|
||||
gorm.Model
|
||||
Name string
|
||||
Permissions map[string]bool
|
||||
Admin bool
|
||||
Users []string
|
||||
}
|
||||
|
||||
func NewGroup(Name string) Group {
|
||||
var group Group
|
||||
group.Permissions = make(map[string]bool)
|
||||
return group
|
||||
}
|
||||
|
||||
//Create group
|
||||
func (g *Group) Create() error {
|
||||
return create(&g)
|
||||
}
|
||||
|
||||
//Read group
|
||||
func (g *Group) Read() error {
|
||||
return read(&g)
|
||||
|
||||
}
|
||||
|
||||
//ReadAll groups
|
||||
func (g *Group) ReadAll() ([]Group, error) {
|
||||
var groups []Group
|
||||
var err error
|
||||
err = readAll(&groups)
|
||||
return groups, err
|
||||
}
|
||||
|
||||
//Update group
|
||||
func (g *Group) Update() error {
|
||||
return update(&g)
|
||||
}
|
||||
|
||||
//Delete group
|
||||
func (g *Group) Delete() error {
|
||||
err := delete(&g)
|
||||
return err
|
||||
}
|
25
models/group_test.go
Normal file
25
models/group_test.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/globalsign/mgo/bson"
|
||||
)
|
||||
|
||||
func TestCreateGroup(t *testing.T) {
|
||||
group := NewGroup("test")
|
||||
group.Users = append(group.Users, bson.NewObjectId())
|
||||
group.Permissions["test"] = true
|
||||
t.Log(group.Create())
|
||||
}
|
||||
|
||||
func TestReadGroup(t *testing.T) {
|
||||
var group Group
|
||||
group.Read("name", "test")
|
||||
t.Log(group)
|
||||
}
|
||||
|
||||
func TestReadAllGroup(t *testing.T) {
|
||||
var group Group
|
||||
t.Log(group.ReadAll())
|
||||
}
|
78
models/model.go
Normal file
78
models/model.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/jinzhu/gorm/dialects/postgres" //
|
||||
)
|
||||
|
||||
const (
|
||||
host = "localhost"
|
||||
port = 5432
|
||||
user = "test"
|
||||
password = "test"
|
||||
dbname = "test"
|
||||
)
|
||||
|
||||
var psqlInfo string
|
||||
var db *gorm.DB
|
||||
|
||||
func init() {
|
||||
psqlInfo = fmt.Sprintf("host=%s port=%d user=%s "+
|
||||
"password=%s dbname=%s sslmode=disable",
|
||||
host, port, user, password, dbname)
|
||||
DB()
|
||||
|
||||
}
|
||||
func DB() (*gorm.DB, error) {
|
||||
if db == nil {
|
||||
db, err := gorm.Open("postgres", psqlInfo)
|
||||
db.LogMode(true)
|
||||
return db, err
|
||||
}
|
||||
return db, nil
|
||||
|
||||
}
|
||||
|
||||
func create(m interface{}) error {
|
||||
db, err := DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Create(m).Error
|
||||
}
|
||||
|
||||
func read(m interface{}) error {
|
||||
db, err := DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Where(m).First(m).Error
|
||||
}
|
||||
|
||||
func readAll(m interface{}) error {
|
||||
db, err := DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Find(m).Error
|
||||
}
|
||||
|
||||
func update(m interface{}) error {
|
||||
db, err := DB()
|
||||
defer db.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Save(m).Error
|
||||
}
|
||||
|
||||
func delete(m interface{}) error {
|
||||
db, err := DB()
|
||||
defer db.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Delete(m).Error
|
||||
}
|
37
models/model_test.go
Normal file
37
models/model_test.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetSession(t *testing.T) {
|
||||
GetMongoSession()
|
||||
}
|
||||
|
||||
func TestGetCollection(t *testing.T) {
|
||||
GetCollection("test")
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
create("user", &User{Name: "Ale"})
|
||||
}
|
||||
|
||||
func TestReadAll(t *testing.T) {
|
||||
var u []User
|
||||
readAll("user", "", nil, &u)
|
||||
t.Log(u)
|
||||
}
|
||||
|
||||
func TestRead(t *testing.T) {
|
||||
var u User
|
||||
read("user", "name", "Ann", &u)
|
||||
t.Log(u)
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
update("test", "name", "Ale", &User{Name: "Bob", Email: "z"})
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
t.Log(delete("user", "name", "Ann"))
|
||||
}
|
33
models/post.go
Normal file
33
models/post.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
//Post model
|
||||
type Post struct {
|
||||
gorm.Model
|
||||
Title string
|
||||
Author string
|
||||
Published time.Time
|
||||
LastEdited time.Time
|
||||
Content []byte
|
||||
}
|
||||
|
||||
//Create new post
|
||||
func (p Post) Create() error {
|
||||
return create(&p)
|
||||
}
|
||||
|
||||
func (p *Post) Read() (*Post, error) {
|
||||
err := read(&p)
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (p Post) ReadAll() ([]Post, error) {
|
||||
var posts []Post
|
||||
err := readAll(&posts)
|
||||
return posts, err
|
||||
}
|
1
models/post_test.go
Normal file
1
models/post_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package models_test
|
55
models/session.go
Normal file
55
models/session.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.1248.nz/1248/Otfe/misc/cookie"
|
||||
"github.com/globalsign/mgo/bson"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
//Session model
|
||||
type Session struct {
|
||||
gorm.Model
|
||||
UserID bson.ObjectId
|
||||
ExpireAt time.Time
|
||||
IP string
|
||||
}
|
||||
|
||||
//Create session and set LoginTime
|
||||
func (s *Session) Create() error {
|
||||
return create(&s)
|
||||
}
|
||||
|
||||
//Read session
|
||||
func (s *Session) Read() error {
|
||||
return read(&s)
|
||||
|
||||
}
|
||||
|
||||
//Update LastSeenTime
|
||||
func (s *Session) Update() error {
|
||||
s.UpdatedAt = time.Now()
|
||||
return update(&s)
|
||||
}
|
||||
|
||||
//Delete session
|
||||
func (s *Session) Delete() error {
|
||||
return delete(s)
|
||||
}
|
||||
|
||||
//Get session from http request and check if it is valid
|
||||
func (s *Session) Get(r *http.Request) error {
|
||||
//Read session cookie
|
||||
var err error
|
||||
s.Model.ID, err = cookie.Read(r, "session")
|
||||
|
||||
if err == nil {
|
||||
err = s.Read()
|
||||
}
|
||||
return err
|
||||
}
|
51
models/session_test.go
Normal file
51
models/session_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"git.1248.nz/1248/Otfe/misc/b64"
|
||||
"git.1248.nz/1248/Otfe/misc/helpers"
|
||||
"git.1248.nz/1248/Otfe/misc/rand"
|
||||
)
|
||||
|
||||
func TestSessionCreate(t *testing.T) {
|
||||
var s1, s2 Session
|
||||
s1.ID, _ = rand.B64String(32)
|
||||
if s1.Create() != nil {
|
||||
t.Fail()
|
||||
}
|
||||
read("session", "_id", s1.ID, &s2)
|
||||
|
||||
if s1.ID != s2.ID {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSessionRead(t *testing.T) {
|
||||
var s1, s2 Session
|
||||
s1.ID, _ = rand.B64String(32)
|
||||
if create("session", &s1) != nil {
|
||||
t.Fatal("Failed to create session")
|
||||
}
|
||||
if s2.Read(s1.ID) != nil {
|
||||
t.Fatal("Failed to read session")
|
||||
}
|
||||
if s1.ID != s2.ID {
|
||||
t.Fatal("Ids don't match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
DBWipeCollection("session")
|
||||
var s1, s2 Session
|
||||
s1.ID, _ = rand.B64String(32)
|
||||
s1.Create()
|
||||
c := &http.Cookie{Name: "session",
|
||||
Value: b64.Encode(s1.ID)}
|
||||
request, err := http.NewRequest("GET", "/", nil)
|
||||
helpers.Ok(t, err)
|
||||
request.AddCookie(c)
|
||||
s2.Get(request)
|
||||
helpers.Equals(t, s1, s2)
|
||||
}
|
11
models/testhelpers.go
Normal file
11
models/testhelpers.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package models
|
||||
|
||||
//DBWipeCollection removes all data from the
|
||||
//specifed collections
|
||||
func DBWipeCollection(collections ...string) {
|
||||
for _, collection := range collections {
|
||||
c, s := GetCollection(collection)
|
||||
defer s.Close()
|
||||
c.RemoveAll(nil)
|
||||
}
|
||||
}
|
80
models/user.go
Normal file
80
models/user.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/globalsign/mgo/bson"
|
||||
)
|
||||
|
||||
//User model
|
||||
type User struct {
|
||||
ID bson.ObjectId `bson:"_id,omitempty"`
|
||||
Email string `bson:"email"`
|
||||
Name string `bson:"name"`
|
||||
Username string `bson:"username"`
|
||||
Password string `bson:"password"`
|
||||
PrimaryGroup bson.ObjectId `bson:"primarygroup,omitempty"`
|
||||
Groups []bson.ObjectId `bson:"groups,omitempty"`
|
||||
Session string
|
||||
}
|
||||
|
||||
//Create user
|
||||
func (u *User) Create() error {
|
||||
var user User
|
||||
read("user", "email", u.Email, &user)
|
||||
if u.Email == user.Email {
|
||||
return errors.New("Email all ready used")
|
||||
}
|
||||
return create("user", &u)
|
||||
|
||||
}
|
||||
|
||||
//Read user
|
||||
func (u *User) Read(key string, value interface{}) error {
|
||||
err := read("user", key, value, &u)
|
||||
if err != nil {
|
||||
return errors.New("User doesn't exist")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//ReadAll users
|
||||
func (u *User) ReadAll() ([]User, error) {
|
||||
var users []User
|
||||
var err error
|
||||
err = readAll("user", "", nil, &users)
|
||||
return users, err
|
||||
|
||||
}
|
||||
|
||||
//Update user
|
||||
func (u *User) Update() error {
|
||||
return update("user", "_id", u.ID, &u)
|
||||
}
|
||||
|
||||
//Delete user
|
||||
func (u *User) Delete(key string, value string) error {
|
||||
err := delete("user", key, value)
|
||||
return err
|
||||
}
|
||||
|
||||
//HasPermission check if a given user is admin or has a given permisssion
|
||||
func (u *User) HasPermission(perm string) bool {
|
||||
var group Group
|
||||
//Check primary group
|
||||
err := group.Read("_id", u.PrimaryGroup)
|
||||
fmt.Println(group.Admin)
|
||||
if err == nil && (group.Admin == true || group.Permissions[perm] == true) {
|
||||
|
||||
return true
|
||||
}
|
||||
//Check other groups
|
||||
for id := range u.Groups {
|
||||
err = group.Read("_id", id)
|
||||
if err == nil && (group.Admin || group.Permissions[perm]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
79
models/user_test.go
Normal file
79
models/user_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/globalsign/mgo/bson"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func TestSeed(t *testing.T) {
|
||||
DBWipeCollection("user")
|
||||
password1, _ := hashPassword("a")
|
||||
user1 := User{Username: "Bob", Name: "Bob", Email: "bob@bob.com", Password: password1}
|
||||
t.Log(user1.Create())
|
||||
user2 := User{Username: "Fred", Name: "Fred", Email: "b"}
|
||||
user2.Create()
|
||||
user3 := User{Username: "Lucy", Name: "Lucy", Email: "c"}
|
||||
user3.Create()
|
||||
user4 := User{Username: "Ann", Name: "Ann", Email: "d"}
|
||||
user4.Create()
|
||||
user5 := User{Username: "Ted", Name: "Ted", Email: "e"}
|
||||
user5.Create()
|
||||
user6 := User{Username: "Egor", Name: "Egor", Email: "f"}
|
||||
user6.Create()
|
||||
}
|
||||
|
||||
func TestCreateUser(t *testing.T) {
|
||||
user := User{Email: "iojkmiojko", Username: "rytiuhmhhjm,",
|
||||
ID: bson.NewObjectId()}
|
||||
t.Log(user.Create())
|
||||
}
|
||||
|
||||
func TestUserRead(t *testing.T) {
|
||||
var user User
|
||||
t.Log(user.Read("name", "Ann"))
|
||||
t.Log(user)
|
||||
}
|
||||
|
||||
func TestUserReadAll(t *testing.T) {
|
||||
var user User
|
||||
t.Log(user.ReadAll())
|
||||
}
|
||||
|
||||
func TestHasPermission(t *testing.T) {
|
||||
c, s := GetCollection("user")
|
||||
c.RemoveAll(nil)
|
||||
s.Close()
|
||||
c, s = GetCollection("group")
|
||||
c.RemoveAll(nil)
|
||||
s.Close()
|
||||
group := NewGroup("test")
|
||||
group.ID = bson.NewObjectId()
|
||||
group.Create()
|
||||
user := User{Name: "user", Email: "a", PrimaryGroup: group.ID}
|
||||
user.Create()
|
||||
//Check no permission
|
||||
if user.HasPermission("") {
|
||||
t.Fail()
|
||||
}
|
||||
//Check admin permission
|
||||
group.Admin = true
|
||||
group.Update()
|
||||
if !user.HasPermission("") {
|
||||
t.Fail()
|
||||
}
|
||||
group.Admin = false
|
||||
//Check permission
|
||||
group.Permissions["perm"] = true
|
||||
group.Update()
|
||||
if !user.HasPermission("perm") {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func hashPassword(password string) (string, error) {
|
||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||
return string(bytes), err
|
||||
}
|
Reference in New Issue
Block a user