Create and update Blogs
Started work on author info
This commit is contained in:
@@ -111,6 +111,8 @@ If an error status code is returned then the body will be as follows.
|
|||||||
* API Key is invalid or does not have the needed permission for the request.
|
* API Key is invalid or does not have the needed permission for the request.
|
||||||
* invalidBody
|
* invalidBody
|
||||||
* Body of the request is malformed.
|
* Body of the request is malformed.
|
||||||
|
* unauthorized
|
||||||
|
* User is not authorized for the given task or no user token is given.
|
||||||
* badRequest
|
* badRequest
|
||||||
* Some part of your request is invalid
|
* Some part of your request is invalid
|
||||||
* internal
|
* internal
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ A simple blog module for darkstorm-backend.
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
id: "authorID",
|
id: "authorID",
|
||||||
|
name: "author name",
|
||||||
about: "about",
|
about: "about",
|
||||||
picurl: "picture URL"
|
picurl: "picture URL"
|
||||||
}
|
}
|
||||||
@@ -26,6 +27,7 @@ Must have a auth token for a user with the `"blog": "admin"` permission.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
name: "author name",
|
||||||
about: "about",
|
about: "about",
|
||||||
picurl: "picture url"
|
picurl: "picture url"
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-8
@@ -2,6 +2,7 @@ package blog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@@ -35,21 +36,58 @@ func (b *BlogApp) AboutMe() (*Author, error) {
|
|||||||
return &aboutMe, nil
|
return &aboutMe, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) GetAuthorInfo(w http.ResponseWriter, r *http.Request) {
|
func (b *BlogApp) reqAuthorInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
res := b.authCol.FindOne(context.Background(), r.PathValue("authorID"))
|
||||||
|
if res.Err() == mongo.ErrNoDocuments {
|
||||||
|
backend.ReturnError(w, http.StatusNotFound, "notFound", "Author with ID "+r.PathValue("authorID")+" not found")
|
||||||
|
return
|
||||||
|
} else if res.Err() != nil {
|
||||||
|
log.Println("error getting author info:", res.Err())
|
||||||
|
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server Error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var auth Author
|
||||||
|
err := res.Decode(&auth)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error decoding author info:", err)
|
||||||
|
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server Error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
json.NewEncoder(w).Encode(auth)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BlogApp) addAuthorInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
hdr, err := b.back.VerifyHeader(w, r, "blogManagement", false)
|
||||||
|
if hdr == nil {
|
||||||
|
if err != nil {
|
||||||
|
log.Println("request key parsing error:", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else if hdr.Key.AppID != "blog" {
|
||||||
|
backend.ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application is unauthorized")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if hdr.User == nil || hdr.User.Perm["blog"] != "admin" {
|
||||||
|
backend.ReturnError(w, http.StatusUnauthorized, "unauthorized", "Application is unauthorized")
|
||||||
|
return
|
||||||
|
}
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) SetAuthorInfo(w http.ResponseWriter, r *http.Request) {
|
func (b *BlogApp) updateAuthorInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
hdr, err := b.back.VerifyHeader(w, r, "managment", true)
|
hdr, err := b.back.VerifyHeader(w, r, "blogManagement", false)
|
||||||
if hdr == nil {
|
if hdr == nil {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error verifying apiKey:", err)
|
log.Println("request key parsing error:", err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
} else if hdr.Key.AppID != "blog" {
|
||||||
if hdr.Key.AppID != "blog" {
|
backend.ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application is unauthorized")
|
||||||
backend.ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application not authorized")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if hdr.User == nil || hdr.User.Perm["blog"] != "admin" {
|
||||||
|
backend.ReturnError(w, http.StatusUnauthorized, "unauthorized", "Application is unauthorized")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//TODO
|
||||||
}
|
}
|
||||||
|
|||||||
+100
-19
@@ -6,8 +6,10 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
||||||
|
"github.com/google/uuid"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
@@ -19,8 +21,8 @@ type Blog struct {
|
|||||||
Favicon string `json:"favicon" bson:"favicon"`
|
Favicon string `json:"favicon" bson:"favicon"`
|
||||||
Title string `json:"title" bson:"title"`
|
Title string `json:"title" bson:"title"`
|
||||||
Blog string `json:"blog" bson:"blog"`
|
Blog string `json:"blog" bson:"blog"`
|
||||||
CreateTime int `json:"createTime" bson:"createTime"`
|
CreateTime int64 `json:"createTime" bson:"createTime"`
|
||||||
UpdateTime int `json:"updateTime" bson:"updateTime"`
|
UpdateTime int64 `json:"updateTime" bson:"updateTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) ConvertBlog(blog *Blog) {
|
func (b *BlogApp) ConvertBlog(blog *Blog) {
|
||||||
@@ -41,7 +43,7 @@ func (b *BlogApp) GetAuthor(blog *Blog) (*Author, error) {
|
|||||||
return &author, err
|
return &author, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) GetBlog(ID string) (*Blog, error) {
|
func (b *BlogApp) Blog(ID string) (*Blog, error) {
|
||||||
res := b.blogCol.FindOne(context.Background(), bson.M{"_id": ID})
|
res := b.blogCol.FindOne(context.Background(), bson.M{"_id": ID})
|
||||||
if res.Err() != nil {
|
if res.Err() != nil {
|
||||||
if res.Err() == mongo.ErrNoDocuments {
|
if res.Err() == mongo.ErrNoDocuments {
|
||||||
@@ -58,13 +60,13 @@ func (b *BlogApp) GetBlog(ID string) (*Blog, error) {
|
|||||||
return &blog, nil
|
return &blog, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) Blog(w http.ResponseWriter, r *http.Request) {
|
func (b *BlogApp) reqBlog(w http.ResponseWriter, r *http.Request) {
|
||||||
blogID := r.PathValue("blogID")
|
blogID := r.PathValue("blogID")
|
||||||
if blogID == "" {
|
if blogID == "" {
|
||||||
backend.ReturnError(w, http.StatusBadRequest, "badRequest", "Must provide a blogID")
|
backend.ReturnError(w, http.StatusBadRequest, "badRequest", "Must provide a blogID")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
blog, err := b.GetBlog(blogID)
|
blog, err := b.Blog(blogID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == backend.ErrNotFound {
|
if err == backend.ErrNotFound {
|
||||||
backend.ReturnError(w, http.StatusNotFound, "notFound", "Not blog found with the given ID")
|
backend.ReturnError(w, http.StatusNotFound, "notFound", "Not blog found with the given ID")
|
||||||
@@ -77,23 +79,102 @@ func (b *BlogApp) Blog(w http.ResponseWriter, r *http.Request) {
|
|||||||
json.NewEncoder(w).Encode(blog)
|
json.NewEncoder(w).Encode(blog)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) CreateBlog(w http.ResponseWriter, r *http.Request) {
|
func (b *BlogApp) createBlog(w http.ResponseWriter, r *http.Request) {
|
||||||
hdr, err := b.back.ParseHeader(r)
|
hdr, err := b.back.VerifyHeader(w, r, "blogManagement", false)
|
||||||
|
if hdr == nil {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == backend.ErrApiKeyUnauthorized{
|
log.Println("request key parsing error:", err)
|
||||||
backend.ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application unauthorized")
|
}
|
||||||
|
return
|
||||||
|
} else if hdr.Key.AppID != "blog" {
|
||||||
|
backend.ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application is unauthorized")
|
||||||
return
|
return
|
||||||
}else if err == backend.ErrTokenUnauthorized{
|
|
||||||
backend.ReturnError(w, http.StatusUnauthorized, "")
|
|
||||||
}
|
}
|
||||||
|
if hdr.User == nil || hdr.User.Perm["blog"] != "admin" {
|
||||||
|
backend.ReturnError(w, http.StatusUnauthorized, "unauthorized", "Application is unauthorized")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
var newBlog Blog
|
||||||
|
err = json.NewDecoder(r.Body).Decode(&newBlog)
|
||||||
|
r.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
backend.ReturnError(w, http.StatusBadRequest, "badRequest", "Bad request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
id, err := uuid.NewV7()
|
||||||
|
if err != nil {
|
||||||
|
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server Error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tim := time.Now().Unix()
|
||||||
|
newBlog.ID = id.String()
|
||||||
|
newBlog.CreateTime = tim
|
||||||
|
newBlog.UpdateTime = tim
|
||||||
|
newBlog.Author = hdr.User.Username
|
||||||
|
_, err = b.blogCol.InsertOne(context.Background(), newBlog)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error when inserting new blog:", err)
|
||||||
|
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server Error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) UpdateBlog(w http.ResponseWriter, r *http.Request) {
|
func (b *BlogApp) updateBlog(w http.ResponseWriter, r *http.Request) {
|
||||||
//TODO
|
hdr, err := b.back.VerifyHeader(w, r, "blogManagement", false)
|
||||||
|
if hdr == nil {
|
||||||
|
if err != nil {
|
||||||
|
log.Println("request key parsing error:", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else if hdr.Key.AppID != "blog" {
|
||||||
|
backend.ReturnError(w, http.StatusUnauthorized, "invalidKey", "Application is unauthorized")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if hdr.User == nil || hdr.User.Perm["blog"] != "admin" {
|
||||||
|
backend.ReturnError(w, http.StatusUnauthorized, "unauthorized", "Application is unauthorized")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.PathValue("blogID") == "" {
|
||||||
|
backend.ReturnError(w, http.StatusBadRequest, "badRequest", "Bad request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var reqUpdRaw map[string]string
|
||||||
|
err = json.NewDecoder(r.Body).Decode(&reqUpdRaw)
|
||||||
|
r.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
backend.ReturnError(w, http.StatusBadRequest, "badRequest", "Bad request")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reqUpd := bson.M{}
|
||||||
|
if fav, ok := reqUpdRaw["favicon"]; ok && fav != "" {
|
||||||
|
reqUpd["favicon"] = fav
|
||||||
|
}
|
||||||
|
if titl, ok := reqUpdRaw["title"]; ok && titl != "" {
|
||||||
|
reqUpd["title"] = titl
|
||||||
|
}
|
||||||
|
if blog, ok := reqUpdRaw["blog"]; ok && blog != "" {
|
||||||
|
reqUpd["blog"] = blog
|
||||||
|
}
|
||||||
|
reqUpd["updateTime"] = time.Now().Unix()
|
||||||
|
res, err := b.blogCol.UpdateByID(context.Background(), r.PathValue("blogID"), reqUpd)
|
||||||
|
if err != nil {
|
||||||
|
if err == mongo.ErrNoDocuments {
|
||||||
|
backend.ReturnError(w, http.StatusNotFound, "notFound", "Blog with ID "+r.PathValue("blogID")+" not found")
|
||||||
|
} else {
|
||||||
|
backend.ReturnError(w, http.StatusInternalServerError, "internal", "Server Error")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if res.MatchedCount == 0 {
|
||||||
|
backend.ReturnError(w, http.StatusNotFound, "notFound", "Blog with ID "+r.PathValue("blogID")+" not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) GetLatestBlogs(page int64) ([]Blog, error) {
|
func (b *BlogApp) LatestBlogs(page int64) ([]Blog, error) {
|
||||||
res, err := b.blogCol.Find(context.Background(), bson.M{}, options.Find().
|
res, err := b.blogCol.Find(context.Background(), bson.M{}, options.Find().
|
||||||
SetSort(bson.M{"createTime": 1}).
|
SetSort(bson.M{"createTime": 1}).
|
||||||
SetLimit(5).
|
SetLimit(5).
|
||||||
@@ -115,7 +196,7 @@ func (b *BlogApp) GetLatestBlogs(page int64) ([]Blog, error) {
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) LatestBlogs(w http.ResponseWriter, r *http.Request) {
|
func (b *BlogApp) reqLatestBlogs(w http.ResponseWriter, r *http.Request) {
|
||||||
var page int
|
var page int
|
||||||
var err error
|
var err error
|
||||||
pagQuery := r.URL.Query().Get("page")
|
pagQuery := r.URL.Query().Get("page")
|
||||||
@@ -125,7 +206,7 @@ func (b *BlogApp) LatestBlogs(w http.ResponseWriter, r *http.Request) {
|
|||||||
page = 0
|
page = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blogs, err := b.GetLatestBlogs(int64(page))
|
blogs, err := b.LatestBlogs(int64(page))
|
||||||
if err != nil && err != backend.ErrNotFound {
|
if err != nil && err != backend.ErrNotFound {
|
||||||
log.Println("error getting latest blogs:", err)
|
log.Println("error getting latest blogs:", err)
|
||||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "internal error")
|
backend.ReturnError(w, http.StatusInternalServerError, "internal", "internal error")
|
||||||
@@ -145,7 +226,7 @@ type BlogListResult struct {
|
|||||||
CreateTime int `json:"createTime" bson:"createTime"`
|
CreateTime int `json:"createTime" bson:"createTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) GetBlogList(page int64) ([]BlogListResult, error) {
|
func (b *BlogApp) BlogList(page int64) ([]BlogListResult, error) {
|
||||||
res, err := b.blogCol.Find(context.Background(), bson.M{}, options.Find().
|
res, err := b.blogCol.Find(context.Background(), bson.M{}, options.Find().
|
||||||
SetProjection(bson.M{"_id": 1, "createTime": 1}).
|
SetProjection(bson.M{"_id": 1, "createTime": 1}).
|
||||||
SetSort(bson.M{"createTime": 1}).
|
SetSort(bson.M{"createTime": 1}).
|
||||||
@@ -165,7 +246,7 @@ func (b *BlogApp) GetBlogList(page int64) ([]BlogListResult, error) {
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogApp) BlogList(w http.ResponseWriter, r *http.Request) {
|
func (b *BlogApp) reqBlogList(w http.ResponseWriter, r *http.Request) {
|
||||||
var page int
|
var page int
|
||||||
var err error
|
var err error
|
||||||
pagQuery := r.URL.Query().Get("page")
|
pagQuery := r.URL.Query().Get("page")
|
||||||
@@ -175,7 +256,7 @@ func (b *BlogApp) BlogList(w http.ResponseWriter, r *http.Request) {
|
|||||||
page = 0
|
page = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blogList, err := b.GetBlogList(int64(page))
|
blogList, err := b.BlogList(int64(page))
|
||||||
if err != nil && err != backend.ErrNotFound {
|
if err != nil && err != backend.ErrNotFound {
|
||||||
log.Println("error getting blog list:", err)
|
log.Println("error getting blog list:", err)
|
||||||
backend.ReturnError(w, http.StatusInternalServerError, "internal", "internal error")
|
backend.ReturnError(w, http.StatusInternalServerError, "internal", "internal error")
|
||||||
|
|||||||
@@ -24,11 +24,15 @@ func NewBlogApp(b *backend.Backend, db *mongo.Database, mux *http.ServeMux) *Blo
|
|||||||
}
|
}
|
||||||
out.conv.ImplementDefaults()
|
out.conv.ImplementDefaults()
|
||||||
// setup mux
|
// setup mux
|
||||||
mux.HandleFunc("GET /blog", out.LatestBlogs)
|
mux.HandleFunc("GET /blog", out.reqLatestBlogs)
|
||||||
mux.HandleFunc("GET /blog/list", out.BlogList)
|
mux.HandleFunc("GET /blog/list", out.reqBlogList)
|
||||||
mux.HandleFunc("GET /blog/{blogID}", out.Blog)
|
mux.HandleFunc("GET /blog/{blogID}", out.reqBlog)
|
||||||
|
mux.HandleFunc("POST /blog", out.createBlog)
|
||||||
|
mux.HandleFunc("POST /blog/{blogID}", out.updateBlog)
|
||||||
|
|
||||||
mux.HandleFunc("POST /blog", out.CreateBlog)
|
mux.HandleFunc("GET /author/{authorID}", out.reqAuthorInfo)
|
||||||
|
mux.HandleFunc("POST /author", out.addAuthorInfo)
|
||||||
|
mux.HandleFunc("POST /author/{authorID}", out.updateAuthorInfo)
|
||||||
//TODO
|
//TODO
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user