WIP Branch completed: Overhaul of site logic, removed comments, repositories

This commit is contained in:
2022-03-09 04:20:27 +00:00
parent cd7a34be0c
commit 860115cbcc
40 changed files with 730 additions and 564 deletions

93
repos/admin_repo.go Normal file
View 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
View 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")
}
}

View File

@@ -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
}

View File

@@ -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")
}
}

View File

@@ -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
}

View File

@@ -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.")
}
}