WIP Branch completed: Overhaul of site logic, removed comments, repositories
This commit is contained in:
93
repos/admin_repo.go
Normal file
93
repos/admin_repo.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package repos
|
||||
|
||||
/*
|
||||
Copyright (C) 2022 Rawley Fowler
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.Rawley Fowler, 2022
|
||||
*/
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gitlab.com/rawleyifowler/site-rework/models"
|
||||
"gitlab.com/rawleyifowler/site-rework/utils"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type AdminRepo struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewAdminRepo(dsnPath string) *AdminRepo {
|
||||
c := AdminRepo{}
|
||||
var err error
|
||||
c.DB, err = utils.CreateDatabase(utils.LoadDSN(dsnPath))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.DB.AutoMigrate(&models.Administrator{})
|
||||
return &c
|
||||
}
|
||||
|
||||
func (ar *AdminRepo) CreateAdmin(a *models.Administrator) error {
|
||||
if a.Password == "" ||
|
||||
a.Username == "" {
|
||||
return errors.New("Administrators must have a valid username and password")
|
||||
}
|
||||
if len(a.Password) < 8 {
|
||||
return errors.New("Passwords must have a length of atleast 8")
|
||||
}
|
||||
a.Token = uuid.New().String()
|
||||
a.Password = fmt.Sprintf("%x", string(sha256.New().Sum([]byte(a.Password))))
|
||||
err := ar.DB.Table("administrators").Create(a).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ar *AdminRepo) GetAdminByToken(k string) (*models.Administrator, error) {
|
||||
if k == "" {
|
||||
return nil, errors.New("Session key cannot be blank")
|
||||
}
|
||||
if len(k) != 36 {
|
||||
return nil, errors.New("Valid sessions keys are always 36 byte utf-8 strings")
|
||||
}
|
||||
var a *models.Administrator
|
||||
err := ar.DB.Table("administrators").Where(&models.Administrator{Token: k}).Scan(a).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (ar *AdminRepo) GetAdminByCredentials(uname, pword string) (*models.Administrator, error) {
|
||||
if uname == "" ||
|
||||
pword == "" {
|
||||
return nil, errors.New("Username or password mustn't be empty")
|
||||
}
|
||||
if len(pword) < 8 {
|
||||
return nil, errors.New("Password length must be no less than 8")
|
||||
}
|
||||
pword = fmt.Sprintf("%x", string(sha256.New().Sum([]byte(pword))))
|
||||
var a models.Administrator
|
||||
err := ar.DB.Table("administrators").Where(&models.Administrator{Username: uname, Password: pword}).First(&a).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &a, nil
|
||||
}
|
||||
67
repos/admin_repo_test.go
Normal file
67
repos/admin_repo_test.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package repos
|
||||
|
||||
/*
|
||||
Copyright (C) 2022 Rawley Fowler
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.Rawley Fowler, 2022
|
||||
*/
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitlab.com/rawleyifowler/site-rework/models"
|
||||
)
|
||||
|
||||
var test_admin_repo = NewAdminRepo("dsn")
|
||||
|
||||
func TestCreateAdmin(t *testing.T) {
|
||||
err := test_admin_repo.CreateAdmin(&models.Administrator{})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: You cannot create an admin with empty credentials")
|
||||
}
|
||||
err = test_admin_repo.CreateAdmin(&models.Administrator{Username: "", Password: "12345678"})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: You cannot create an admin with empty credentials")
|
||||
}
|
||||
err = test_admin_repo.CreateAdmin(&models.Administrator{Username: "12345678", Password: ""})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: You cannot create an admin with empty credentials")
|
||||
}
|
||||
err = test_admin_repo.CreateAdmin(&models.Administrator{Username: "valid_username", Password: "invalid"})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: You cannot create an admin with a password less than 8 characters")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAdminByToken(t *testing.T) {
|
||||
_, err := test_admin_repo.GetAdminByToken("")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Error should be thrown when an empty session key is provided")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAdminByCredentials(t *testing.T) {
|
||||
_, err := test_admin_repo.GetAdminByCredentials("", "")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Error should be thrown if empty credentials are given")
|
||||
}
|
||||
_, err = test_admin_repo.GetAdminByCredentials("1234", "")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Error should be thrown if empty credentials are given")
|
||||
}
|
||||
_, err = test_admin_repo.GetAdminByCredentials("", "123456789")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Error should be thrown if empty credentials are given")
|
||||
}
|
||||
}
|
||||
@@ -1 +1,107 @@
|
||||
package repos
|
||||
|
||||
/*
|
||||
Copyright (C) 2022 Rawley Fowler
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.Rawley Fowler, 2022
|
||||
*/
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"gitlab.com/rawleyifowler/site-rework/models"
|
||||
"gitlab.com/rawleyifowler/site-rework/utils"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type BlogRepo struct {
|
||||
DB *gorm.DB
|
||||
initialized bool
|
||||
}
|
||||
|
||||
func NewBlogRepo(dsnPath string) *BlogRepo {
|
||||
b := BlogRepo{}
|
||||
var err error
|
||||
b.DB, err = utils.CreateDatabase(utils.LoadDSN(dsnPath))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b.DB.AutoMigrate(&models.BlogPost{})
|
||||
return &b
|
||||
}
|
||||
|
||||
func (b *BlogRepo) CreateBlogPost(p *models.BlogPost) error {
|
||||
if p == nil {
|
||||
return errors.New("Blog post must not be nil")
|
||||
}
|
||||
if p.Title == "" ||
|
||||
p.Content == "" ||
|
||||
p.Url == "" {
|
||||
return errors.New("Blog posts must be fully formed")
|
||||
}
|
||||
err := b.DB.Table("blog_posts").Create(p).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BlogRepo) GetBlogByUrl(url string) (*models.BlogPost, error) {
|
||||
if url == "" {
|
||||
return nil, errors.New("Cannot query by empty value")
|
||||
}
|
||||
var post models.BlogPost
|
||||
err := b.DB.Table("blog_posts").Where(&models.BlogPost{Url: url}).Scan(&post).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &post, nil
|
||||
}
|
||||
|
||||
func (b *BlogRepo) GetAllBlogPosts() (*[]models.BlogPost, error) {
|
||||
posts := new([]models.BlogPost)
|
||||
err := b.DB.Table("blog_posts").Scan(posts).Error
|
||||
if err != nil {
|
||||
return nil, errors.New("Could not load all posts from database")
|
||||
}
|
||||
return posts, nil
|
||||
}
|
||||
|
||||
func (b *BlogRepo) UpdateExistingPost(p *models.BlogPost) error {
|
||||
if p == nil {
|
||||
return errors.New("Cannot update with nil value for post")
|
||||
}
|
||||
if p.Url == "" {
|
||||
return errors.New("Url must exist to update a blog post record")
|
||||
}
|
||||
err := b.DB.Table("blog_posts").Save(p).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BlogRepo) DeleteExistingPost(p *models.BlogPost) error {
|
||||
if p == nil {
|
||||
return errors.New("Cannot delete with nil value for post")
|
||||
}
|
||||
if p.Url == "" {
|
||||
return errors.New("Url must exist to delete a blog post record")
|
||||
}
|
||||
err := b.DB.Table("blog_posts").Delete(p).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package repos
|
||||
|
||||
/*
|
||||
Copyright (C) 2022 Rawley Fowler
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.Rawley Fowler, 2022
|
||||
*/
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitlab.com/rawleyifowler/site-rework/models"
|
||||
)
|
||||
|
||||
var test_blog_repo = NewBlogRepo("dsn")
|
||||
|
||||
func TestGetBlogByUrl(t *testing.T) {
|
||||
_, err := test_blog_repo.GetBlogByUrl("")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Empty values of url for get blog by url should return an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateBlogPost(t *testing.T) {
|
||||
err := test_blog_repo.CreateBlogPost(&models.BlogPost{})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Blog posts must be fully formed")
|
||||
}
|
||||
|
||||
err = test_blog_repo.CreateBlogPost(&models.BlogPost{Title: "abc"})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Blog posts must be fully formed, title, content, url")
|
||||
}
|
||||
|
||||
err = test_blog_repo.CreateBlogPost(nil)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Cannot create blog posts from nil values")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
package repos
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"gitlab.com/rawleyifowler/site-rework/models"
|
||||
"gitlab.com/rawleyifowler/site-rework/utils"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CommentRepo struct {
|
||||
DB *gorm.DB
|
||||
Initialized bool
|
||||
}
|
||||
|
||||
func NewCommentRepo(dsnPath string) (*CommentRepo, error) {
|
||||
c := CommentRepo{}
|
||||
err := c.Initialize(dsnPath)
|
||||
if err != nil {
|
||||
return &c, err
|
||||
}
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func (c *CommentRepo) Initialize(path string) error {
|
||||
dsn := utils.LoadDSN(path)
|
||||
var err error
|
||||
c.DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommentRepo) GetCommentById(id uint) (*models.Comment, error) {
|
||||
if id == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var comm models.Comment
|
||||
c.DB.Where(&models.Comment{Id: id}).First(&comm)
|
||||
return &comm, nil
|
||||
}
|
||||
|
||||
func (c *CommentRepo) CreateComment(comm *models.Comment) error {
|
||||
if comm == nil {
|
||||
return errors.New("nil comment")
|
||||
}
|
||||
err := c.DB.Create(comm).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// nil return means no errors, yay!
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommentRepo) GetCommentsByAssociatedPost(title string) (*[]models.Comment, error) {
|
||||
if len(title) < 1 {
|
||||
return nil, errors.New("empty associated post title")
|
||||
}
|
||||
var comms []models.Comment
|
||||
err := c.DB.Where(&models.Comment{AssociatedPost: title}).Scan(&comms).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &comms, nil
|
||||
}
|
||||
|
||||
func (c *CommentRepo) GetCommentsByAuthor(auth string) (*[]models.Comment, error) {
|
||||
if len(auth) < 1 {
|
||||
return nil, errors.New("empty author name")
|
||||
}
|
||||
var comms []models.Comment
|
||||
err := c.DB.Where(&models.Comment{Author: auth}).Scan(&comms).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &comms, nil
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package repos
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitlab.com/rawleyifowler/site-rework/models"
|
||||
)
|
||||
|
||||
var cr *CommentRepo
|
||||
|
||||
func TestInitialize(t *testing.T) {
|
||||
var err error
|
||||
cr, err = NewCommentRepo("dsn")
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCommentById(t *testing.T) {
|
||||
const ID uint = 1
|
||||
const AUTHOR string = "Whoops"
|
||||
const CONTENT string = "Uhhhhhhhh that wasn't supposed to happen..."
|
||||
// This comment will exist forever on the database, it's part of the test blog post.
|
||||
x := models.Comment{Id: ID, Author: AUTHOR, Content: CONTENT}
|
||||
y, err := cr.GetCommentById(ID)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected: Comment with id: %d should be found without errors.", ID)
|
||||
}
|
||||
if x.Id != y.Id ||
|
||||
x.Author != y.Author ||
|
||||
x.Content != y.Content {
|
||||
t.Fatalf("Expected(left expected, right result):\nid -> %d == %d\nauthor -> %s == %s\ncontent -> %s == %s",
|
||||
ID, y.Id, AUTHOR, y.Author, CONTENT, y.Content)
|
||||
}
|
||||
_, err := cr.GetCommentById(0)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Values of less than or equal to 0 are considered illegal values for comment id")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCommentsByAssociatedPost(t *testing.T) {
|
||||
_, err := cr.GetCommentsByAssociatedPost("")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Empty values are considered illegal for associated post")
|
||||
}
|
||||
// Wild associated post should return empty array
|
||||
post, err := cr.GetCommentsByAssociatedPost("kjdoJDOWIJWKIJALSKAJSAKIJDOIAj")
|
||||
if len(*post) > 0 {
|
||||
t.Fatalf("Expected: Should return empty array")
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("Expected: Non existant post should not throw error, just empty array")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCommentsByAuthor(t *testing.T) {
|
||||
_, err := cr.GetCommentsByAuthor("")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: An empty author value should throw an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateComment(t *testing.T) {
|
||||
err := cr.CreateComment(nil)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Nil values should result in errors when trying to create comments")
|
||||
}
|
||||
err = cr.CreateComment(&models.Comment{})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Empty or incomplete models should result in errors.")
|
||||
}
|
||||
err = cr.CreateComment(&models.Comment{Author: "Chuck"})
|
||||
if err == nil {
|
||||
t.Fatalf("Expected: Empty or incomplete models should result in errors.")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user