v2 #43
|
@ -62,7 +62,7 @@ func (s *AuthorService) CreateToken(name string) (string, error) {
|
|||
return fmt.Sprintf("%s.%x", name, hash.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func (s *AuthorService) ValidateToken(token string) bool {
|
||||
func (s *AuthorService) ValidateToken(token string) (bool, string) {
|
||||
parts := strings.Split(token, ".")
|
||||
witness := parts[len(parts)-1]
|
||||
name := strings.Join(parts[:len(parts)-1], ".")
|
||||
|
@ -70,7 +70,7 @@ func (s *AuthorService) ValidateToken(token string) bool {
|
|||
hash := sha256.New()
|
||||
_, err := hash.Write([]byte(name + s.getSecretKey()))
|
||||
if err != nil {
|
||||
return false
|
||||
return false, ""
|
||||
}
|
||||
return fmt.Sprintf("%x", hash.Sum(nil)) == witness
|
||||
return fmt.Sprintf("%x", hash.Sum(nil)) == witness, name
|
||||
}
|
||||
|
|
|
@ -71,9 +71,15 @@ func TestAuthorValidateToken(t *testing.T) {
|
|||
token, err := authorService.CreateToken("test")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, authorService.ValidateToken(token))
|
||||
require.False(t, authorService.ValidateToken(token[:len(token)-2]))
|
||||
require.False(t, authorService.ValidateToken("test"))
|
||||
require.False(t, authorService.ValidateToken("test.test"))
|
||||
require.False(t, authorService.ValidateToken(strings.Replace(token, "test", "test1", 1)))
|
||||
valid, name := authorService.ValidateToken(token)
|
||||
require.True(t, valid)
|
||||
require.Equal(t, "test", name)
|
||||
valid, _ = authorService.ValidateToken(token[:len(token)-2])
|
||||
require.False(t, valid)
|
||||
valid, _ = authorService.ValidateToken("test")
|
||||
require.False(t, valid)
|
||||
valid, _ = authorService.ValidateToken("test.test")
|
||||
require.False(t, valid)
|
||||
valid, _ = authorService.ValidateToken(strings.Replace(token, "test", "test1", 1))
|
||||
require.False(t, valid)
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@ import (
|
|||
)
|
||||
|
||||
var userPath string
|
||||
var author string
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(importCmd)
|
||||
|
||||
importCmd.Flags().StringVarP(&userPath, "path", "p", "", "Path to the user folder")
|
||||
importCmd.MarkFlagRequired("path")
|
||||
importCmd.Flags().StringVarP(&author, "author", "a", "", "The author name")
|
||||
importCmd.MarkFlagRequired("author")
|
||||
}
|
||||
|
||||
var importCmd = &cobra.Command{
|
||||
|
@ -56,63 +59,64 @@ var importCmd = &cobra.Command{
|
|||
app.BinaryService.CreateEntryFile(file, fileData, entry)
|
||||
}
|
||||
|
||||
var entry model.Entry
|
||||
|
||||
switch post.Meta.Type {
|
||||
case "article":
|
||||
article := model.Article{}
|
||||
article.SetID(post.Id)
|
||||
article.SetPublishedAt(&post.Meta.Date)
|
||||
article.SetMetaData(&model.ArticleMetaData{
|
||||
entry = &model.Article{}
|
||||
entry.SetID(post.Id)
|
||||
entry.SetPublishedAt(&post.Meta.Date)
|
||||
entry.SetMetaData(&model.ArticleMetaData{
|
||||
Title: post.Meta.Title,
|
||||
Content: post.Content,
|
||||
})
|
||||
app.EntryService.Create(&article)
|
||||
case "bookmark":
|
||||
|
||||
case "reply":
|
||||
|
||||
case "photo":
|
||||
photo := model.Image{}
|
||||
photo.SetID(post.Id)
|
||||
photo.SetPublishedAt(&post.Meta.Date)
|
||||
photo.SetMetaData(&model.ImageMetaData{
|
||||
entry = &model.Image{}
|
||||
entry.SetID(post.Id)
|
||||
entry.SetPublishedAt(&post.Meta.Date)
|
||||
entry.SetMetaData(&model.ImageMetaData{
|
||||
Title: post.Meta.Title,
|
||||
Content: post.Content,
|
||||
ImageId: post.Meta.PhotoPath,
|
||||
})
|
||||
app.EntryService.Create(&photo)
|
||||
case "note":
|
||||
note := model.Note{}
|
||||
note.SetID(post.Id)
|
||||
note.SetPublishedAt(&post.Meta.Date)
|
||||
note.SetMetaData(&model.NoteMetaData{
|
||||
entry = &model.Note{}
|
||||
entry.SetID(post.Id)
|
||||
entry.SetPublishedAt(&post.Meta.Date)
|
||||
entry.SetMetaData(&model.NoteMetaData{
|
||||
Content: post.Content,
|
||||
})
|
||||
app.EntryService.Create(¬e)
|
||||
case "recipe":
|
||||
recipe := model.Recipe{}
|
||||
recipe.SetID(post.Id)
|
||||
recipe.SetPublishedAt(&post.Meta.Date)
|
||||
recipe.SetMetaData(&model.RecipeMetaData{
|
||||
entry = &model.Recipe{}
|
||||
entry.SetID(post.Id)
|
||||
entry.SetPublishedAt(&post.Meta.Date)
|
||||
entry.SetMetaData(&model.RecipeMetaData{
|
||||
Title: post.Meta.Title,
|
||||
Yield: post.Meta.Recipe.Yield,
|
||||
Duration: post.Meta.Recipe.Duration,
|
||||
Ingredients: post.Meta.Recipe.Ingredients,
|
||||
Content: post.Content,
|
||||
})
|
||||
app.EntryService.Create(&recipe)
|
||||
case "page":
|
||||
page := model.Page{}
|
||||
page.SetID(post.Id)
|
||||
page.SetPublishedAt(&post.Meta.Date)
|
||||
page.SetMetaData(&model.PageMetaData{
|
||||
entry = &model.Page{}
|
||||
entry.SetID(post.Id)
|
||||
entry.SetPublishedAt(&post.Meta.Date)
|
||||
entry.SetMetaData(&model.PageMetaData{
|
||||
Title: post.Meta.Title,
|
||||
Content: post.Content,
|
||||
})
|
||||
app.EntryService.Create(&page)
|
||||
default:
|
||||
panic("Unknown type")
|
||||
}
|
||||
|
||||
if entry != nil {
|
||||
entry.SetAuthorId(author)
|
||||
app.EntryService.Create(entry)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ type Entry interface {
|
|||
ID() string
|
||||
Content() EntryContent
|
||||
PublishedAt() *time.Time
|
||||
AuthorId() string
|
||||
MetaData() interface{}
|
||||
|
||||
// Optional: can return empty string
|
||||
|
@ -16,6 +17,7 @@ type Entry interface {
|
|||
SetID(id string)
|
||||
SetPublishedAt(publishedAt *time.Time)
|
||||
SetMetaData(metaData interface{})
|
||||
SetAuthorId(authorId string)
|
||||
}
|
||||
|
||||
type EntryMetaData interface {
|
||||
|
@ -24,6 +26,7 @@ type EntryMetaData interface {
|
|||
type EntryBase struct {
|
||||
id string
|
||||
publishedAt *time.Time
|
||||
authorId string
|
||||
}
|
||||
|
||||
func (e *EntryBase) ID() string {
|
||||
|
@ -41,3 +44,11 @@ func (e *EntryBase) SetID(id string) {
|
|||
func (e *EntryBase) SetPublishedAt(publishedAt *time.Time) {
|
||||
e.publishedAt = publishedAt
|
||||
}
|
||||
|
||||
func (e *EntryBase) AuthorId() string {
|
||||
return e.authorId
|
||||
}
|
||||
|
||||
func (e *EntryBase) SetAuthorId(authorId string) {
|
||||
e.authorId = authorId
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ type sqlEntry struct {
|
|||
Type string `db:"type"`
|
||||
PublishedAt *time.Time `db:"published_at"`
|
||||
MetaData *string `db:"meta_data"`
|
||||
AuthorId string `db:"author_id"`
|
||||
}
|
||||
|
||||
type DefaultEntryRepo struct {
|
||||
|
@ -43,7 +44,7 @@ func (r *DefaultEntryRepo) Create(entry model.Entry) error {
|
|||
entry.SetID(uuid.New().String())
|
||||
}
|
||||
|
||||
_, err = r.db.Exec("INSERT INTO entries (id, type, published_at, meta_data) VALUES (?, ?, ?, ?)", entry.ID(), t, entry.PublishedAt(), metaDataJson)
|
||||
_, err = r.db.Exec("INSERT INTO entries (id, type, published_at, author_id, meta_data) VALUES (?, ?, ?, ?, ?)", entry.ID(), t, entry.PublishedAt(), entry.AuthorId(), metaDataJson)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -118,7 +119,7 @@ func (r *DefaultEntryRepo) Update(entry model.Entry) error {
|
|||
metaDataJson, _ = json.Marshal(entry.MetaData())
|
||||
}
|
||||
|
||||
_, err = r.db.Exec("UPDATE entries SET published_at = ?, meta_data = ? WHERE id = ?", entry.PublishedAt(), metaDataJson, entry.ID())
|
||||
_, err = r.db.Exec("UPDATE entries SET published_at = ?, author_id = ?, meta_data = ? WHERE id = ?", entry.PublishedAt(), entry.AuthorId(), metaDataJson, entry.ID())
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -131,6 +132,7 @@ func NewEntryRepository(db Database, register *app.EntryTypeRegistry) repository
|
|||
id TEXT PRIMARY KEY,
|
||||
type TEXT NOT NULL,
|
||||
published_at DATETIME,
|
||||
author_id TEXT NOT NULL,
|
||||
meta_data TEXT NOT NULL
|
||||
);
|
||||
`)
|
||||
|
@ -151,5 +153,6 @@ func (r *DefaultEntryRepo) sqlEntryToEntry(entry sqlEntry) (model.Entry, error)
|
|||
e.SetID(entry.Id)
|
||||
e.SetPublishedAt(entry.PublishedAt)
|
||||
e.SetMetaData(metaData)
|
||||
e.SetAuthorId(entry.AuthorId)
|
||||
return e, nil
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ func TestRepoCreate(t *testing.T) {
|
|||
entry := &test.MockEntry{}
|
||||
now := time.Now()
|
||||
entry.SetPublishedAt(&now)
|
||||
entry.SetAuthorId("authorId")
|
||||
entry.SetMetaData(&test.MockEntryMetaData{
|
||||
Str: "str",
|
||||
Number: 1,
|
||||
|
@ -37,6 +38,7 @@ func TestRepoCreate(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, entry.ID(), entry2.ID())
|
||||
require.Equal(t, entry.Content(), entry2.Content())
|
||||
require.Equal(t, entry.AuthorId(), entry2.AuthorId())
|
||||
require.Equal(t, entry.PublishedAt().Unix(), entry2.PublishedAt().Unix())
|
||||
meta := entry.MetaData().(*test.MockEntryMetaData)
|
||||
meta2 := entry2.MetaData().(*test.MockEntryMetaData)
|
||||
|
@ -113,6 +115,7 @@ func TestRepoUpdate(t *testing.T) {
|
|||
entry := &test.MockEntry{}
|
||||
now := time.Now()
|
||||
entry.SetPublishedAt(&now)
|
||||
entry.SetAuthorId("authorId")
|
||||
entry.SetMetaData(&test.MockEntryMetaData{
|
||||
Str: "str",
|
||||
Number: 1,
|
||||
|
@ -124,6 +127,7 @@ func TestRepoUpdate(t *testing.T) {
|
|||
entry2 := &test.MockEntry{}
|
||||
now2 := time.Now()
|
||||
entry2.SetPublishedAt(&now2)
|
||||
entry.SetAuthorId("authorId2")
|
||||
entry2.SetMetaData(&test.MockEntryMetaData{
|
||||
Str: "str2",
|
||||
Number: 2,
|
||||
|
@ -138,6 +142,7 @@ func TestRepoUpdate(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, entry3.Content(), entry2.Content())
|
||||
require.Equal(t, entry3.PublishedAt().Unix(), entry2.PublishedAt().Unix())
|
||||
require.Equal(t, entry3.AuthorId(), entry2.AuthorId())
|
||||
meta := entry3.MetaData().(*test.MockEntryMetaData)
|
||||
meta2 := entry2.MetaData().(*test.MockEntryMetaData)
|
||||
require.Equal(t, meta.Str, meta2.Str)
|
||||
|
|
|
@ -70,6 +70,7 @@ func (h *EditorHandler) HandlePost(c *fiber.Ctx) error {
|
|||
// create entry
|
||||
now := time.Now()
|
||||
entry.SetPublishedAt(&now)
|
||||
entry.SetAuthorId(c.Locals("author").(string))
|
||||
|
||||
err = h.entrySvc.Create(entry)
|
||||
if err != nil {
|
||||
|
|
|
@ -32,9 +32,9 @@ func (h *EntryHandler) Handle(c *fiber.Ctx) error {
|
|||
return err
|
||||
}
|
||||
|
||||
author, err := h.authorSvc.FindByName("h4kor")
|
||||
author, err := h.authorSvc.FindByName(entry.AuthorId())
|
||||
if err != nil {
|
||||
return err
|
||||
author = &model.Author{}
|
||||
}
|
||||
|
||||
return render.RenderTemplateWithBase(c, "views/entry", entryData{Entry: entry, Author: author})
|
||||
|
|
|
@ -22,10 +22,13 @@ func (m *AuthMiddleware) Handle(c *fiber.Ctx) error {
|
|||
}
|
||||
|
||||
// check token
|
||||
valid := m.authorService.ValidateToken(token)
|
||||
valid, name := m.authorService.ValidateToken(token)
|
||||
if !valid {
|
||||
return c.Redirect("/auth/login")
|
||||
}
|
||||
|
||||
// set author name to context
|
||||
c.Locals("author", name)
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue